| | |
| | | import com.sleepycat.je.EnvironmentFailureException; |
| | | |
| | | import java.util.logging.Level; |
| | | |
| | | import org.opends.server.api.DiskSpaceMonitorHandler; |
| | | import org.opends.server.backends.jeb.importLDIF.*; |
| | | import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn; |
| | | import org.opends.server.admin.std.server.MonitorProviderCfg; |
| | | import org.opends.server.api.Backend; |
| | | import org.opends.server.api.MonitorProvider; |
| | | import org.opends.server.api.AlertGenerator; |
| | |
| | | import org.opends.server.core.ModifyOperation; |
| | | import org.opends.server.core.ModifyDNOperation; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.extensions.DiskSpaceMonitor; |
| | | import org.opends.server.util.LDIFException; |
| | | import org.opends.server.util.RuntimeInformation; |
| | | import org.opends.server.util.Validator; |
| | |
| | | */ |
| | | public class BackendImpl |
| | | extends Backend |
| | | implements ConfigurationChangeListener<LocalDBBackendCfg>, AlertGenerator |
| | | implements ConfigurationChangeListener<LocalDBBackendCfg>, AlertGenerator, |
| | | DiskSpaceMonitorHandler |
| | | { |
| | | /** |
| | | * The tracer object for the debug logger. |
| | |
| | | private final AtomicInteger threadWriteCount = new AtomicInteger(0); |
| | | |
| | | /** |
| | | * A list of monitor providers created for this backend instance. |
| | | */ |
| | | private ArrayList<MonitorProvider<?>> monitorProviders = |
| | | new ArrayList<MonitorProvider<?>>(); |
| | | |
| | | /** |
| | | * The base DNs defined for this backend instance. |
| | | */ |
| | | private DN[] baseDNs; |
| | | |
| | | private MonitorProvider<?> rootContainerMonitor; |
| | | private DiskSpaceMonitor diskMonitor; |
| | | |
| | | /** |
| | | * The controls supported by this backend. |
| | | */ |
| | |
| | | } |
| | | |
| | | // Register a monitor provider for the environment. |
| | | MonitorProvider<? extends MonitorProviderCfg> monitorProvider = |
| | | rootContainer.getMonitorProvider(); |
| | | monitorProviders.add(monitorProvider); |
| | | DirectoryServer.registerMonitorProvider(monitorProvider); |
| | | 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); |
| | |
| | | } |
| | | } |
| | | |
| | | // Deregister our monitor providers. |
| | | for (MonitorProvider<?> monitor : monitorProviders) |
| | | { |
| | | DirectoryServer.deregisterMonitorProvider( |
| | | monitor.getMonitorInstanceName().toLowerCase()); |
| | | } |
| | | monitorProviders = new ArrayList<MonitorProvider<?>>(); |
| | | DirectoryServer.deregisterMonitorProvider( |
| | | rootContainerMonitor.getMonitorInstanceName()); |
| | | |
| | | DirectoryServer.deregisterMonitorProvider( |
| | | diskMonitor.getMonitorInstanceName()); |
| | | |
| | | // We presume the server will prevent more operations coming into this |
| | | // backend, but there may be existing operations already in the |
| | |
| | | public void addEntry(Entry entry, AddOperation addOperation) |
| | | throws DirectoryException, CanceledOperationException |
| | | { |
| | | checkDiskSpace(addOperation); |
| | | writerBegin(); |
| | | DN entryDN = entry.getDN(); |
| | | |
| | |
| | | public void deleteEntry(DN entryDN, DeleteOperation deleteOperation) |
| | | throws DirectoryException, CanceledOperationException |
| | | { |
| | | checkDiskSpace(deleteOperation); |
| | | writerBegin(); |
| | | |
| | | EntryContainer ec; |
| | |
| | | ModifyOperation modifyOperation) throws DirectoryException, |
| | | CanceledOperationException |
| | | { |
| | | checkDiskSpace(modifyOperation); |
| | | writerBegin(); |
| | | |
| | | DN entryDN = newEntry.getDN(); |
| | |
| | | @Override() |
| | | public void renameEntry(DN currentDN, Entry entry, |
| | | ModifyDNOperation modifyDNOperation) |
| | | throws DirectoryException, CanceledOperationException { |
| | | throws DirectoryException, CanceledOperationException |
| | | { |
| | | checkDiskSpace(modifyDNOperation); |
| | | writerBegin(); |
| | | |
| | | EntryContainer currentContainer; |
| | |
| | | |
| | | baseDNs = newBaseDNs; |
| | | } |
| | | |
| | | if(cfg.getDiskFullThreshold() != newCfg.getDiskFullThreshold() || |
| | | cfg.getDiskLowThreshold() != newCfg.getDiskLowThreshold()) |
| | | { |
| | | diskMonitor.setFullThreshold(newCfg.getDiskFullThreshold()); |
| | | diskMonitor.setLowThreshold(newCfg.getDiskLowThreshold()); |
| | | } |
| | | |
| | | // Put the new configuration in place. |
| | | this.cfg = newCfg; |
| | | } |
| | |
| | | |
| | | alerts.put(ALERT_TYPE_BACKEND_ENVIRONMENT_UNUSABLE, |
| | | ALERT_DESCRIPTION_BACKEND_ENVIRONMENT_UNUSABLE); |
| | | alerts.put(ALERT_TYPE_DISK_SPACE_LOW, |
| | | ALERT_DESCRIPTION_DISK_SPACE_LOW); |
| | | alerts.put(ALERT_TYPE_DISK_FULL, |
| | | ALERT_DESCRIPTION_DISK_FULL); |
| | | return alerts; |
| | | } |
| | | |
| | |
| | | new EntryCachePreloader(this); |
| | | preloader.preload(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void diskLowThresholdReached(long bytesFree) { |
| | | Message msg = ERR_JEB_DISK_LOW_THRESHOLD_REACHED.get( |
| | | getFileForPath(cfg.getDBDirectory()).getPath(), cfg.getBackendId(), |
| | | bytesFree, Math.max(cfg.getDiskLowThreshold(), |
| | | cfg.getDiskFullThreshold())); |
| | | DirectoryServer.sendAlertNotification(this, |
| | | ALERT_TYPE_DISK_SPACE_LOW, msg); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void diskFullThresholdReached(long bytesFree) { |
| | | Message msg = ERR_JEB_DISK_FULL_THRESHOLD_REACHED.get( |
| | | getFileForPath(cfg.getDBDirectory()).getPath(), cfg.getBackendId(), |
| | | bytesFree, Math.max(cfg.getDiskLowThreshold(), |
| | | cfg.getDiskFullThreshold())); |
| | | DirectoryServer.sendAlertNotification(this, |
| | | ALERT_TYPE_DISK_FULL, msg); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void diskSpaceRestored(long bytesFree) { |
| | | Message msg = NOTE_JEB_DISK_SPACE_RESTORED.get(bytesFree, |
| | | getFileForPath(cfg.getDBDirectory()).getPath(), cfg.getBackendId(), |
| | | Math.max(cfg.getDiskLowThreshold(), |
| | | cfg.getDiskFullThreshold())); |
| | | logError(msg); |
| | | } |
| | | |
| | | private void checkDiskSpace(Operation operation) throws DirectoryException |
| | | { |
| | | if(diskMonitor.isFullThresholdReached() || |
| | | (diskMonitor.isLowThresholdReached() && operation != null && |
| | | !operation.getClientConnection().hasPrivilege( |
| | | Privilege.BYPASS_LOCKDOWN, operation))) |
| | | { |
| | | throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, |
| | | WARN_JEB_OUT_OF_DISK_SPACE.get()); |
| | | } |
| | | } |
| | | } |