| | |
| | | * Portions Copyright 2006-2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.backends; |
| | | import org.opends.messages.Message; |
| | | |
| | | |
| | | |
| | |
| | | import java.util.Set; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.std.server.RootDSEBackendCfg; |
| | |
| | | import org.opends.server.util.LDIFWriter; |
| | | import org.opends.server.util.Validator; |
| | | |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.messages.BackendMessages.*; |
| | | import static org.opends.messages.ConfigMessages. |
| | | ERR_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY; |
| | | |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a backend to hold the Directory Server root DSE. It is a |
| | | * kind of meta-backend in that it will dynamically generate the root DSE entry |
| | |
| | | */ |
| | | private static final DebugTracer TRACER = getTracer(); |
| | | |
| | | |
| | | |
| | | // The set of standard "static" attributes that we will always include in the |
| | | // root DSE entry and won't change while the server is running. |
| | | private ArrayList<Attribute> staticDSEAttributes; |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void configureBackend(Configuration config) |
| | | throws ConfigException |
| | | { |
| | |
| | | configEntryDN = config.dn(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void initializeBackend() |
| | | throws ConfigException, InitializationException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Performs any necessary work to finalize this backend, including closing any |
| | | * underlying databases or connections and deregistering any suffixes that it |
| | | * manages with the Directory Server. This may be called during the |
| | | * Directory Server shutdown process or if a backend is disabled with the |
| | | * server online. It must not return until the backend is closed. |
| | | * <BR><BR> |
| | | * This method may not throw any exceptions. If any problems are encountered, |
| | | * then they may be logged but the closure should progress as completely as |
| | | * possible. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void finalizeBackend() |
| | | { |
| | | currentConfig.removeChangeListener(this); |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of base-level DNs that may be used within this backend. |
| | | * |
| | | * @return The set of base-level DNs that may be used within this backend. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public DN[] getBaseDNs() |
| | | { |
| | | return baseDNs; |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public synchronized long getEntryCount() |
| | | { |
| | | // There is always just a single entry in this backend. |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the data associated with this backend may be considered |
| | | * local (i.e., in a repository managed by the Directory Server) rather than |
| | | * remote (i.e., in an external repository accessed by the Directory Server |
| | | * but managed through some other means). |
| | | * |
| | | * @return <CODE>true</CODE> if the data associated with this backend may be |
| | | * considered local, or <CODE>false</CODE> if it is remote. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean isLocal() |
| | | { |
| | | // For the purposes of this method, this is a local backend. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException |
| | | @Override() |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult hasSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | | long ret = numSubordinates(entryDN); |
| | | if(ret < 0) |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public long numSubordinates(DN entryDN) throws DirectoryException |
| | | @Override() |
| | | public long numSubordinates(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | | if (entryDN == null || ! entryDN.isNullDN()) |
| | | { |
| | |
| | | |
| | | for (DN subBase : baseMap.keySet()) |
| | | { |
| | | |
| | | Backend b = baseMap.get(subBase); |
| | | Entry subBaseEntry = b.getEntry(subBase); |
| | | if (subBaseEntry != null) |
| | | if (DirectoryServer.entryExists(subBase)) |
| | | { |
| | | count++; |
| | | } |
| | |
| | | return count; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the requested entry from this backend. |
| | | * |
| | | * @param entryDN The distinguished name of the entry to retrieve. |
| | | * |
| | | * @return The requested entry, or <CODE>null</CODE> if the entry does not |
| | | * exist. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while trying to retrieve |
| | | * the entry. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public Entry getEntry(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether an entry with the specified DN exists in the backend. |
| | | * The default implementation obtains a read lock and calls |
| | | * <CODE>getEntry</CODE>, but backend implementations may override this with a |
| | | * more efficient version that does not require a lock. The caller is not |
| | | * required to hold any locks on the specified DN. |
| | | * |
| | | * @param entryDN The DN of the entry for which to determine existence. |
| | | * |
| | | * @return <CODE>true</CODE> if the specified entry exists in this backend, |
| | | * or <CODE>false</CODE> if it does not. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while trying to make the |
| | | * determination. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean entryExists(DN entryDN) |
| | | throws DirectoryException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided entry to this backend. This method must ensure that the |
| | | * entry is appropriate for the backend and that no entry already exists with |
| | | * the same DN. |
| | | * |
| | | * @param entry The entry to add to this backend. |
| | | * @param addOperation The add operation with which the new entry is |
| | | * associated. This may be <CODE>null</CODE> for adds |
| | | * performed internally. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while trying to add the |
| | | * entry. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void addEntry(Entry entry, AddOperation addOperation) |
| | | throws DirectoryException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Removes the specified entry from this backend. This method must ensure |
| | | * that the entry exists and that it does not have any subordinate entries |
| | | * (unless the backend supports a subtree delete operation and the client |
| | | * included the appropriate information in the request). |
| | | * |
| | | * @param entryDN The DN of the entry to remove from this backend. |
| | | * @param deleteOperation The delete operation with which this action is |
| | | * associated. This may be <CODE>null</CODE> for |
| | | * deletes performed internally. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while trying to remove the |
| | | * entry. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void deleteEntry(DN entryDN, DeleteOperation deleteOperation) |
| | | throws DirectoryException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Replaces the specified entry with the provided entry in this backend. The |
| | | * backend must ensure that an entry already exists with the same DN as the |
| | | * provided entry. |
| | | * |
| | | * @param entry The new entry to use in place of the existing |
| | | * entry with the same DN. |
| | | * @param modifyOperation The modify operation with which this action is |
| | | * associated. This may be <CODE>null</CODE> for |
| | | * modifications performed internally. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while trying to replace |
| | | * the entry. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void replaceEntry(Entry entry, ModifyOperation modifyOperation) |
| | | throws DirectoryException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Moves and/or renames the provided entry in this backend, altering any |
| | | * subordinate entries as necessary. This must ensure that an entry already |
| | | * exists with the provided current DN, and that no entry exists with the |
| | | * target DN of the provided entry. |
| | | * |
| | | * @param currentDN The current DN of the entry to be replaced. |
| | | * @param entry The new content to use for the entry. |
| | | * @param modifyDNOperation The modify DN operation with which this action |
| | | * is associated. This may be <CODE>null</CODE> |
| | | * for modify DN operations performed internally. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while trying to perform |
| | | * the rename. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void renameEntry(DN currentDN, Entry entry, |
| | | ModifyDNOperation modifyDNOperation) |
| | | throws DirectoryException |
| | |
| | | |
| | | |
| | | /** |
| | | * Processes the specified search in this backend. Matching entries should be |
| | | * provided back to the core server using the |
| | | * <CODE>SearchOperation.returnEntry</CODE> method. |
| | | * |
| | | * @param searchOperation The search operation to be processed. |
| | | * |
| | | * @throws DirectoryException If a problem occurs while processing the |
| | | * search. |
| | | * |
| | | * @throws CancelledOperationException If this backend noticed and reacted |
| | | * to a request to cancel or abandon the |
| | | * add operation. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void search(SearchOperation searchOperation) |
| | | throws DirectoryException, CancelledOperationException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the OIDs of the controls that may be supported by this backend. |
| | | * |
| | | * @return The OIDs of the controls that may be supported by this backend. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public HashSet<String> getSupportedControls() |
| | | { |
| | | return supportedControls; |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the OIDs of the features that may be supported by this backend. |
| | | * |
| | | * @return The OIDs of the features that may be supported by this backend. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public HashSet<String> getSupportedFeatures() |
| | | { |
| | | return supportedFeatures; |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this backend provides a mechanism to export the data it |
| | | * contains to an LDIF file. |
| | | * |
| | | * @return <CODE>true</CODE> if this backend provides an LDIF export |
| | | * mechanism, or <CODE>false</CODE> if not. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean supportsLDIFExport() |
| | | { |
| | | // We will only export the DSE entry itself. |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void exportLDIF(LDIFExportConfig exportConfig) |
| | | throws DirectoryException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this backend provides a mechanism to import its data from |
| | | * an LDIF file. |
| | | * |
| | | * @return <CODE>true</CODE> if this backend provides an LDIF import |
| | | * mechanism, or <CODE>false</CODE> if not. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean supportsLDIFImport() |
| | | { |
| | | // This backend does not support LDIF imports. |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LDIFImportResult importLDIF(LDIFImportConfig importConfig) |
| | | throws DirectoryException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this backend provides a backup mechanism of any kind. |
| | | * This method is used by the backup process when backing up all backends to |
| | | * determine whether this backend is one that should be skipped. It should |
| | | * only return <CODE>true</CODE> for backends that it is not possible to |
| | | * archive directly (e.g., those that don't store their data locally, but |
| | | * rather pass through requests to some other repository). |
| | | * |
| | | * @return <CODE>true</CODE> if this backend provides any kind of backup |
| | | * mechanism, or <CODE>false</CODE> if it does not. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean supportsBackup() |
| | | { |
| | | // This backend does not provide a backup/restore mechanism. |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this backend provides a mechanism to perform a backup of |
| | | * its contents in a form that can be restored later, based on the provided |
| | | * configuration. |
| | | * |
| | | * @param backupConfig The configuration of the backup for which to |
| | | * make the determination. |
| | | * @param unsupportedReason A buffer to which a message can be appended |
| | | * explaining why the requested backup is not |
| | | * supported. |
| | | * |
| | | * @return <CODE>true</CODE> if this backend provides a mechanism for |
| | | * performing backups with the provided configuration, or |
| | | * <CODE>false</CODE> if not. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean supportsBackup(BackupConfig backupConfig, |
| | | StringBuilder unsupportedReason) |
| | | { |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void createBackup(BackupConfig backupConfig) |
| | | throws DirectoryException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Removes the specified backup if it is possible to do so. |
| | | * |
| | | * @param backupDirectory The backup directory structure with which the |
| | | * specified backup is associated. |
| | | * @param backupID The backup ID for the backup to be removed. |
| | | * |
| | | * @throws DirectoryException If it is not possible to remove the specified |
| | | * backup for some reason (e.g., no such backup |
| | | * exists or there are other backups that are |
| | | * dependent upon it). |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void removeBackup(BackupDirectory backupDirectory, |
| | | String backupID) |
| | | throws DirectoryException |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this backend provides a mechanism to restore a backup. |
| | | * |
| | | * @return <CODE>true</CODE> if this backend provides a mechanism for |
| | | * restoring backups, or <CODE>false</CODE> if not. |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean supportsRestore() |
| | | { |
| | | // This backend does not provide a backup/restore mechanism. |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void restoreBackup(RestoreConfig restoreConfig) |
| | | throws DirectoryException |
| | | { |