RootContainer.java revision 664be7d7d84b5c78001d984bd4ab51caa5273b80
/*
* 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-2010 Sun Microsystems, Inc.
* Portions Copyright 2011-2015 ForgeRock AS
*/
/**
* Wrapper class for the JE environment. Root container holds all the entry
* containers for each base DN. It also maintains all the openings and closings
* of the entry containers.
*/
{
/** Logs the progress of the import. */
private static final class ImportProgress implements Runnable
{
private final LDIFReader reader;
private long previousCount;
private long previousTime;
{
}
public void run()
{
if (deltaTime == 0)
{
return;
}
}
}
private static final int IMPORT_PROGRESS_INTERVAL = 10000;
/** The JE database environment. */
/** The backend to which this entry root container belongs. */
private final BackendImpl<?> backend;
/** The backend configuration. */
private final PluggableBackendCfg config;
/** The database environment monitor for this JE environment. */
private DatabaseEnvironmentMonitor monitor;
/** The base DNs contained in this root container. */
private final ConcurrentHashMap<DN, EntryContainer> entryContainers = new ConcurrentHashMap<DN, EntryContainer>();
/** The cached value of the next entry identifier to be assigned. */
/** The compressed schema manager for this backend. */
private JECompressedSchema compressedSchema;
/**
* Creates a new RootContainer object. Each root container represents a JE
* environment.
*
* @param config
* The configuration of the JE backend.
* @param backend
* A reference to the JE back end that is creating this root
* container.
*/
{
config.addPluggableChangeListener(this);
}
/**
* Returns the underlying storage engine.
*
* @return the underlying storage engine
*/
{
return storage;
}
/**
* Imports information from an LDIF file into this backend. This method should
* only be called if {@code supportsLDIFImport} returns {@code true}. <p>Note
* that the server will not explicitly initialize this backend before calling
* this method.
*
* @param importConfig
* The configuration to use when performing the import.
* @return information about the result of the import processing.
* @throws DirectoryException
* If a problem occurs while performing the LDIF import.
*/
{//TODO JNR may call importLDIFWithSuccessiveAdds(importConfig) depending on configured import strategy
return importLDIFWithOnDiskMerge(importConfig);
}
private LDIFImportResult importLDIFWithSuccessiveAdds(LDIFImportConfig importConfig) throws DirectoryException
{
try
{
try
{
final LDIFReader reader;
try
{
}
catch (Exception e)
{
LocalizableMessage m = ERR_LDIF_BACKEND_CANNOT_CREATE_LDIF_READER.get(stackTraceToSingleLineString(e));
}
long importCount = 0;
while (true)
{
try
{
{
break;
}
}
catch (LDIFException le)
{
if (!le.canContinueReading())
{
}
continue;
}
{
continue;
}
try
{
importCount++;
}
catch (DirectoryException e)
{
switch (e.getResultCode().asEnum())
{
case ENTRY_ALREADY_EXISTS:
{
}
else
{
}
break;
case NO_SUCH_OBJECT:
break;
default:
// Not sure why it failed.
break;
}
}
}
float rate = 0;
if (importTime > 0)
{
}
logger.info(NOTE_JEB_IMPORT_FINAL_STATUS, reader.getEntriesRead(), importCount, reader.getEntriesIgnored(),
return new LDIFImportResult(reader.getEntriesRead(), reader.getEntriesRejected(), reader.getEntriesIgnored());
}
finally
{
close();
// if not already stopped, then stop it
}
}
catch (DirectoryException e)
{
logger.traceException(e);
throw e;
}
catch (OpenDsException e)
{
logger.traceException(e);
}
catch (Exception e)
{
logger.traceException(e);
}
}
{
}
private LDIFImportResult importLDIFWithOnDiskMerge(final LDIFImportConfig importConfig) throws DirectoryException
{
try
{
final Importer importer = new Importer(importConfig, (PersistitBackendCfg) config); // TODO JNR remove cast
return importer.processImport(this);
}
catch (DirectoryException e)
{
logger.traceException(e);
throw e;
}
catch (OpenDsException e)
{
logger.traceException(e);
}
catch (Exception e)
{
logger.traceException(e);
throw new DirectoryException(getServerErrorResultCode(),
}
}
/**
* Opens the root container.
*
* @throws StorageRuntimeException
* If a database error occurs when creating the environment.
* @throws ConfigException
* If an configuration error occurs while creating the environment.
*/
{
try
{
{
{
}
});
}
catch (Exception e)
{
throw new StorageRuntimeException(e);
}
}
/**
* Opens the entry container for a base DN. If the entry container does not
* exist for the base DN, it will be created. The entry container will be
* opened with the same mode as the root container. Any entry containers
* opened in a read only root container will also be read only. Any entry
* containers opened in a non transactional root container will also be non
* transactional.
*
* @param baseDN
* The base DN of the entry container to open.
* @param txn
* The database transaction
* @return The opened entry container.
* @throws StorageRuntimeException
* If an error occurs while opening the entry container.
* @throws ConfigException
* If an configuration error occurs while opening the entry container.
*/
{
return ec;
}
/**
* Registers the entry container for a base DN.
*
* @param baseDN
* The base DN of the entry container to close.
* @param entryContainer
* The entry container to register for the baseDN.
* @throws InitializationException
* If an error occurs while opening the entry container.
*/
void registerEntryContainer(DN baseDN, EntryContainer entryContainer) throws InitializationException
{
// If an entry container for this baseDN is already open we don't allow
// another to be opened.
{
throw new InitializationException(ERR_JEB_ENTRY_CONTAINER_ALREADY_REGISTERED.get(ec1.getDatabasePrefix(),
baseDN));
}
}
/**
* Opens the entry containers for multiple base DNs.
*
* @param baseDNs
* The base DNs of the entry containers to open.
* @throws StorageRuntimeException
* If a database error occurs while opening the entry container.
* @throws InitializationException
* If an initialization error occurs while opening the entry
* container.
* @throws ConfigException
* If a configuration error occurs while opening the entry
* container.
*/
private void openAndRegisterEntryContainers(WriteableTransaction txn, Set<DN> baseDNs) throws StorageRuntimeException,
{
{
{
}
}
}
/**
* Unregisters the entry container for a base DN.
*
* @param baseDN
* The base DN of the entry container to close.
* @return The entry container that was unregistered or NULL if a entry
* container for the base DN was not registered.
*/
{
}
/**
* Retrieves the compressed schema manager for this backend.
*
* @return The compressed schema manager for this backend.
*/
{
return compressedSchema;
}
/**
* Get the DatabaseEnvironmentMonitor object for JE environment used by this
* root container.
*
* @return The DatabaseEnvironmentMonitor object.
*/
{
{
}
return monitor;
}
/**
* Preload the database cache. There is no preload if the configured preload
* time limit is zero.
*
* @param timeLimit
* The time limit for the preload process.
*/
{
if (timeLimit > 0)
{
// Get a list of all the databases used by the backend.
{
try
{
}
finally
{
}
}
// Sort the list in order of priority.
// Preload each database until we reach the time limit or the cache
// is filled.
try
{
throw new UnsupportedOperationException("Not implemented exception");
}
catch (StorageRuntimeException e)
{
logger.traceException(e);
}
}
}
/**
* Closes this root container.
*
* @throws StorageRuntimeException
* If an error occurs while attempting to close the root container.
*/
void close() throws StorageRuntimeException
{
{
try
{
}
finally
{
}
}
{
}
}
/**
* Return all the entry containers in this root container.
*
* @return The entry containers in this root container.
*/
{
return entryContainers.values();
}
/**
* Returns all the baseDNs this root container stores.
*
* @return The set of DNs this root container stores.
*/
{
return entryContainers.keySet();
}
/**
* Return the entry container for a specific base DN.
*
* @param baseDN
* The base DN of the entry container to retrieve.
* @return The entry container for the base DN.
*/
{
{
{
}
}
return ec;
}
/**
* Get the backend configuration used by this root container.
*
* @return The backend configuration used by this root container.
*/
{
return config;
}
/**
* Get the total number of entries in this root container.
*
* @return The number of entries in this root container
* @throws StorageRuntimeException
* If an error occurs while retrieving the entry count.
*/
long getEntryCount() throws StorageRuntimeException
{
try
{
{
{
long entryCount = 0;
{
try
{
}
finally
{
}
}
return entryCount;
}
});
}
catch (Exception e)
{
throw new StorageRuntimeException(e);
}
}
/**
* Assign the next entry ID.
*
* @return The assigned entry ID.
*/
{
}
/**
* Resets the next entry ID counter to zero. This should only be used after
* clearing all databases.
*/
public void resetNextEntryID()
{
}
/** {@inheritDoc} */
{
// Storage has also registered a change listener, delegate to it.
return true;
}
/** {@inheritDoc} */
{
return new ConfigChangeResult();
}
/**
* Checks the storage has enough resources for an operation.
*
* @param operation the current operation
* @throws DirectoryException if resources are in short supply
*/
{
if (status.isUnusable()
{
}
}
{
// Read operations are always allowed in lock down mode
&& !(operation instanceof SearchOperation)
}
}