/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
* Portions Copyright 2014-2015 ForgeRock AS
*/
/**
* This class defines a backend used to present information about Directory
* Server backups. It will not actually store anything, but upon request will
* retrieve information about the backups that it knows about. The backups will
* be arranged in a hierarchy based on the directory that contains them, and
* it may be possible to dynamically discover new backups if a previously
* unknown backup directory is included in the base DN.
*/
public class BackupBackend
extends Backend<BackupBackendCfg>
implements ConfigurationChangeListener<BackupBackendCfg>
{
/** The current configuration state. */
/** The DN for the base backup entry. */
/** The set of base DNs for this backend. */
/** The backup base entry. */
/** A cache of BackupDirectories. */
/**
* To avoid parsing and reparsing the contents of backup.info files, we
* cache the BackupDirectory for each directory using this class.
*/
private class CachedBackupDirectory
{
/** The path to the 'bak' directory. */
/** The 'backup.info' file. */
/** The last modify time of the backupInfo file. */
private long lastModified;
/** The BackupDirectory parsed at lastModified time. */
/**
* A BackupDirectory that is cached based on the backup descriptor file.
*
* @param directory Path to the backup directory itself.
*/
{
lastModified = -1;
}
/**
* Return a BackupDirectory. This will be recomputed every time the underlying descriptor (backup.info) file
* changes.
*
* @return An up-to-date BackupDirectory
* @throws IOException If a problem occurs while trying to read the contents of the descriptor file.
* @throws ConfigException If the contents of the descriptor file cannot be parsed to create a backup directory
* structure.
*/
throws IOException, ConfigException
{
{
}
return backupDirectory;
}
}
/**
* Creates a new backend with the provided information. All backend
* implementations must implement a default constructor that use
* <CODE>super()</CODE> to invoke this constructor.
*/
public BackupBackend()
{
super();
// Perform all initialization in initializeBackend.
}
/** {@inheritDoc} */
public void configureBackend(BackupBackendCfg config, ServerContext serverContext) throws ConfigException
{
// Make sure that a configuration entry was provided. If not, then we will
// not be able to complete initialization.
{
}
}
/** {@inheritDoc} */
public void openBackend()
{
// Create the set of base DNs that we will handle. In this case, it's just
// the DN of the base backup entry.
try
{
}
catch (Exception e)
{
logger.traceException(e);
throw new InitializationException(message, e);
}
// FIXME -- Deal with this more correctly.
// Determine the set of backup directories that we will use by default.
{
}
// Construct the backup base entry.
for (int i=0; i < numAVAs; i++)
{
}
// Register the backup base as a private suffix.
try
{
}
catch (Exception e)
{
logger.traceException(e);
throw new InitializationException(message, e);
}
}
/** {@inheritDoc} */
public void closeBackend()
{
try
{
}
catch (Exception e)
{
logger.traceException(e);
}
}
/** {@inheritDoc} */
{
return baseDNs;
}
/** {@inheritDoc} */
public long getEntryCount()
{
int numEntries = 1;
{
try
{
// Check to see if the descriptor file exists. If not, then skip this
// backup directory.
if (! descriptorFile.exists())
{
continue;
}
dir.getAbsolutePath());
numEntries++;
}
catch (Exception e) {}
}
return numEntries;
}
/** {@inheritDoc} */
{
// All searches in this backend will always be considered indexed.
return true;
}
/** {@inheritDoc} */
{
if(ret < 0)
{
return ConditionResult.UNDEFINED;
}
}
/** {@inheritDoc} */
}
/** {@inheritDoc} */
return getNumberOfSubordinates(parentDN, false);
}
{
// If the requested entry was the backend base entry, then return
// the number of backup directories.
{
long count = 0;
{
// Check to see if the descriptor file exists. If not, then skip this
// backup directory.
if (! descriptorFile.exists())
{
continue;
}
// If subtree is included, count the number of entries for each
// backup directory.
if (includeSubtree)
{
count++;
try
{
}
catch (Exception e)
{
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, ERR_BACKUP_INVALID_BACKUP_DIRECTORY.get(
entryDN, e.getMessage()));
}
}
count ++;
}
return count;
}
// See if the requested entry was one level below the backend base entry.
// If so, then it must point to a backup directory. Otherwise, it must be
// two levels below the backup base entry and must point to a specific
// backup.
{
return -1;
}
{
long count = 0;
AttributeType t =
{
{
try
{
}
catch (Exception e)
{
return -1;
}
}
}
return count;
}
{
return 0;
}
else
{
return -1;
}
}
/** {@inheritDoc} */
throws DirectoryException
{
// If the requested entry was null, then throw an exception.
{
}
// If the requested entry was the backend base entry, then retrieve it.
{
return backupBaseEntry.duplicate(true);
}
// See if the requested entry was one level below the backend base entry.
// If so, then it must point to a backup directory. Otherwise, it must be
// two levels below the backup base entry and must point to a specific
// backup.
{
}
{
return getBackupDirectoryEntry(entryDN);
}
{
return getBackupEntry(entryDN);
}
else
{
}
}
/**
* Generates an entry for a backup directory based on the provided DN. The
* DN must contain an RDN component that specifies the path to the backup
* directory, and that directory must exist and be a valid backup directory.
*
* @param entryDN The DN of the backup directory entry to retrieve.
*
* @return The requested backup directory entry.
*
* @throws DirectoryException If the specified directory does not exist or
* is not a valid backup directory, or if the DN
* does not specify any backup directory.
*/
throws DirectoryException
{
// Make sure that the DN specifies a backup directory.
if (v == null)
{
backupBaseDN, null);
}
// Get a handle to the backup directory and the information that it
// contains.
try
{
}
catch (ConfigException ce)
{
}
catch (Exception e)
{
logger.traceException(e);
message);
}
// Construct the backup directory entry to return.
return e;
}
/**
* Generates an entry for a backup based on the provided DN. The DN must
* have an RDN component that specifies the backup ID, and the parent DN must
* have an RDN component that specifies the backup directory.
*
* @param entryDN The DN of the backup entry to retrieve.
*
* @return The requested backup entry.
*
* @throws DirectoryException If the specified backup does not exist or is
* invalid.
*/
throws DirectoryException
{
// First, get the backup ID from the entry DN.
}
// Next, get the backup directory from the parent DN.
}
if (v == null) {
}
try {
} catch (ConfigException ce) {
throw newConstraintViolation(ERR_BACKUP_INVALID_BACKUP_DIRECTORY.get(entryDN, ce.getMessageObject()));
} catch (Exception e) {
logger.traceException(e);
.get(getExceptionMessage(e));
message);
}
if (backupInfo == null) {
.getPath());
}
// Construct the backup entry to return.
if (backupDate != null) {
}
}
if (signedHash != null) {
}
if (unsignedHash != null) {
}
}
}
return e;
}
private void putByteString(LinkedHashMap<AttributeType, List<Attribute>> userAttrs, String attrName, byte[] value)
{
}
private void putBoolean(LinkedHashMap<AttributeType, List<Attribute>> attrsMap, String attrName, boolean value)
{
}
{
}
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
// Get the base entry for the search, if possible. If it doesn't exist,
// then this will throw an exception.
// Look at the base DN and see if it's the backup base DN, a backup
// directory entry DN, or a backup entry DN.
{
{
}
{
{
// Check to see if the descriptor file exists. If not, then skip this
// backup directory.
if (! descriptorFile.exists())
{
continue;
}
dir.getAbsolutePath());
try
{
}
catch (Exception e)
{
logger.traceException(e);
continue;
}
{
}
{
}
}
}
}
{
{
}
{
AttributeType t =
}
}
else
{
{
}
{
if (backupEntry == null)
{
}
{
}
}
}
}
private void returnEntries(SearchOperation searchOperation, DN baseDN, SearchFilter filter, List<Attribute> attrList)
{
{
{
try
{
{
{
}
}
}
catch (Exception e)
{
logger.traceException(e);
continue;
}
}
}
}
/** {@inheritDoc} */
{
return Collections.emptySet();
}
/** {@inheritDoc} */
{
return Collections.emptySet();
}
/** {@inheritDoc} */
{
return false;
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
public boolean isConfigurationChangeAcceptable(
{
// We'll accept anything here. The only configurable attribute is the
// default set of backup directories, but that doesn't require any
// validation at this point.
return true;
}
/** {@inheritDoc} */
{
{
}
currentConfig = cfg;
return ccr;
}
/**
* Create a new child DN from a given parent DN. The child RDN is formed
* from a given attribute type and string value.
* @param parentDN The DN of the parent.
* @param rdnAttrType The attribute type of the RDN.
* @param rdnStringValue The string value of the RDN.
* @return A new child DN.
*/
{
}
}