From aaec0227c12c81b76899eb20ff99c947c7715df0 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Tue, 12 May 2015 15:41:46 +0000
Subject: [PATCH] Partial OPENDJ-2016 Implement new on disk merge import strategy based on storage engine
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/SuccessiveAddsImportStrategy.java | 222 ++++++++++++++++++++++
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java | 226 +---------------------
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java | 71 +++++-
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ImportStrategy.java | 49 ++++
4 files changed, 337 insertions(+), 231 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ImportStrategy.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ImportStrategy.java
new file mode 100644
index 0000000..41cf83a
--- /dev/null
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/ImportStrategy.java
@@ -0,0 +1,49 @@
+/*
+ * 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
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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 2015 ForgeRock AS
+ */
+package org.opends.server.backends.pluggable;
+
+import org.opends.server.core.ServerContext;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.LDIFImportConfig;
+import org.opends.server.types.LDIFImportResult;
+
+/** The strategy to use for importing LDIF files. */
+interface ImportStrategy
+{
+ /**
+ * Imports information from an LDIF file into the supplied root container.
+ *
+ * @param importConfig
+ * The configuration to use when performing the import.
+ * @param serverContext
+ * The server context
+ * @return Information about the result of the import processing.
+ * @throws DirectoryException
+ * If a problem occurs while performing the LDIF import.
+ * @see {@link Backend#importLDIF(LDIFImportConfig, ServerContext)}
+ */
+ LDIFImportResult importLDIF(LDIFImportConfig importConfig, RootContainer rootContainer, ServerContext serverContext)
+ throws DirectoryException;
+}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java
index 2358e65..83413c2 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Importer.java
@@ -31,6 +31,7 @@
import static org.opends.server.backends.pluggable.DnKeyFormat.*;
import static org.opends.server.backends.pluggable.EntryIDSet.*;
import static org.opends.server.backends.pluggable.SuffixContainer.*;
+import static org.opends.server.core.DirectoryServer.*;
import static org.opends.server.util.DynamicConstants.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
@@ -85,6 +86,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.ByteSequence;
@@ -127,6 +129,46 @@
*/
final class Importer
{
+ /**
+ * Shim that allows properly constructing an {@link Importer} without polluting
+ * {@link ImportStrategy} and {@link RootContainer} with this importer inner workings.
+ */
+ static final class StrategyImpl implements ImportStrategy
+ {
+ private final PluggableBackendCfg backendCfg;
+
+ public StrategyImpl(PluggableBackendCfg backendCfg)
+ {
+ this.backendCfg = backendCfg;
+ }
+
+ @Override
+ public LDIFImportResult importLDIF(LDIFImportConfig importConfig, RootContainer rootContainer,
+ ServerContext serverContext) throws DirectoryException
+ {
+ try
+ {
+ return new Importer(rootContainer, importConfig, backendCfg, serverContext).processImport();
+ }
+ catch (DirectoryException e)
+ {
+ logger.traceException(e);
+ throw e;
+ }
+ catch (InitializationException | ConfigException e)
+ {
+ logger.traceException(e);
+ throw new DirectoryException(getServerErrorResultCode(), e.getMessageObject(), e);
+ }
+ catch (Exception e)
+ {
+ logger.traceException(e);
+ throw new DirectoryException(getServerErrorResultCode(),
+ LocalizableMessage.raw(stackTraceToSingleLineString(e)), e);
+ }
+ }
+ }
+
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
private static final int TIMER_INTERVAL = 10000;
@@ -853,14 +895,7 @@
rebuildManager.printStopMessage(startTime);
}
- /**
- * Import a LDIF using the specified root container.
- *
- * @return A LDIF result.
- * @throws Exception
- * If the import failed
- */
- public LDIFImportResult processImport() throws Exception
+ private LDIFImportResult processImport() throws Exception
{
try {
try
@@ -2989,17 +3024,15 @@
return timer;
}
- private int getIndexCount() throws ConfigException, StorageRuntimeException,
- InitializationException
+ private int getIndexCount() throws ConfigException, StorageRuntimeException, InitializationException
{
switch (rebuildConfig.getRebuildMode())
{
case ALL:
return getTotalIndexCount(cfg);
case DEGRADED:
- // FIXME: since the storgae is not opened we cannot determine which
- // indexes are degraded. As a workaround, be conservative and assume all
- // indexes need rebuilding.
+ // FIXME: since the storage is not opened we cannot determine which indexes are degraded.
+ // As a workaround, be conservative and assume all indexes need rebuilding.
return getTotalIndexCount(cfg);
default:
return getRebuildListIndexCount(cfg);
@@ -3023,7 +3056,7 @@
{
indexCount += 3;
}
- else if ("dn2uri".equals(lowerName))
+ else if (DN2URI_INDEX_NAME.equals(lowerName))
{
indexCount++;
}
@@ -3057,11 +3090,11 @@
final String indexType = attrIndexParts[1];
if (attrIndexParts.length == 2)
{
- if ("presence".equals(indexType)
- || "equality".equals(indexType)
- || "ordering".equals(indexType)
- || "substring".equals(indexType)
- || "approximate".equals(indexType))
+ if (PRESENCE.toString().equals(indexType)
+ || EQUALITY.toString().equals(indexType)
+ || ORDERING.toString().equals(indexType)
+ || SUBSTRING.toString().equals(indexType)
+ || APPROXIMATE.toString().equals(indexType))
{
indexCount++;
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java
index 91907da..a53ef67 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java
@@ -27,8 +27,6 @@
package org.opends.server.backends.pluggable;
import static org.opends.messages.BackendMessages.*;
-import static org.opends.messages.UtilityMessages.*;
-import static org.opends.server.core.DirectoryServer.*;
import static org.opends.server.util.StaticUtils.*;
import java.util.ArrayList;
@@ -37,8 +35,6 @@
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.forgerock.i18n.LocalizableMessage;
@@ -56,20 +52,15 @@
import org.opends.server.backends.pluggable.spi.StorageStatus;
import org.opends.server.backends.pluggable.spi.WriteOperation;
import org.opends.server.backends.pluggable.spi.WriteableTransaction;
-import org.opends.server.core.DirectoryServer;
import org.opends.server.core.SearchOperation;
import org.opends.server.core.ServerContext;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
-import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.LDIFImportResult;
-import org.opends.server.types.OpenDsException;
import org.opends.server.types.Operation;
import org.opends.server.types.Privilege;
-import org.opends.server.util.LDIFException;
-import org.opends.server.util.LDIFReader;
/**
* Wrapper class for a backend "container". Root container holds all the entry
@@ -78,44 +69,8 @@
*/
public class RootContainer implements ConfigurationChangeListener<PluggableBackendCfg>
{
- /** Logs the progress of the import. */
- private static final class ImportProgress implements Runnable
- {
- private final LDIFReader reader;
- private long previousCount;
- private long previousTime;
-
- public ImportProgress(LDIFReader reader)
- {
- this.reader = reader;
- }
-
- @Override
- public void run()
- {
- long latestCount = reader.getEntriesRead() + 0;
- long deltaCount = latestCount - previousCount;
- long latestTime = System.currentTimeMillis();
- long deltaTime = latestTime - previousTime;
- if (deltaTime == 0)
- {
- return;
- }
- long entriesRead = reader.getEntriesRead();
- long entriesIgnored = reader.getEntriesIgnored();
- long entriesRejected = reader.getEntriesRejected();
- float rate = 1000f * deltaCount / deltaTime;
- logger.info(NOTE_IMPORT_PROGRESS_REPORT, entriesRead, entriesIgnored, entriesRejected, rate);
-
- previousCount = latestCount;
- previousTime = latestTime;
- }
- }
-
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
- private static final int IMPORT_PROGRESS_INTERVAL = 10000;
-
/** The tree storage. */
private Storage storage;
@@ -129,8 +84,8 @@
/** 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. */
- private AtomicLong nextid = new AtomicLong(1);
+ /** Value of the next entryID to be assigned. */
+ private AtomicLong nextEntryID = new AtomicLong(1);
/** The compressed schema manager for this backend. */
private PersistentCompressedSchema compressedSchema;
@@ -166,161 +121,14 @@
}
LDIFImportResult importLDIF(LDIFImportConfig importConfig, ServerContext serverContext) throws DirectoryException
- {//TODO JNR may call importLDIFWithSuccessiveAdds(importConfig) depending on configured import strategy
- return importLDIFWithOnDiskMerge(importConfig, serverContext);
+ {
+ return getImportStrategy().importLDIF(importConfig, this, serverContext);
}
- private LDIFImportResult importLDIFWithSuccessiveAdds(LDIFImportConfig importConfig) throws DirectoryException
+ private ImportStrategy getImportStrategy() throws DirectoryException
{
- try
- {
- ScheduledThreadPoolExecutor timerService = new ScheduledThreadPoolExecutor(1);
- try
- {
- final LDIFReader reader;
- try
- {
- reader = new LDIFReader(importConfig);
- }
- catch (Exception e)
- {
- LocalizableMessage m = ERR_LDIF_BACKEND_CANNOT_CREATE_LDIF_READER.get(stackTraceToSingleLineString(e));
- throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m, e);
- }
-
- long importCount = 0;
- final long startTime = System.currentTimeMillis();
- timerService.scheduleAtFixedRate(new ImportProgress(reader),
- IMPORT_PROGRESS_INTERVAL, IMPORT_PROGRESS_INTERVAL, TimeUnit.MILLISECONDS);
- while (true)
- {
- final Entry entry;
- try
- {
- entry = reader.readEntry();
- if (entry == null)
- {
- break;
- }
- }
- catch (LDIFException le)
- {
- if (!le.canContinueReading())
- {
- LocalizableMessage m = ERR_LDIF_BACKEND_ERROR_READING_LDIF.get(stackTraceToSingleLineString(le));
- throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m, le);
- }
- continue;
- }
-
- final DN dn = entry.getName();
- final EntryContainer ec = getEntryContainer(dn);
- if (ec == null)
- {
- final LocalizableMessage m = ERR_LDIF_SKIP.get(dn);
- logger.error(m);
- reader.rejectLastEntry(m);
- continue;
- }
-
- try
- {
- ec.addEntry(entry, null);
- importCount++;
- }
- catch (DirectoryException e)
- {
- switch (e.getResultCode().asEnum())
- {
- case ENTRY_ALREADY_EXISTS:
- if (importConfig.replaceExistingEntries())
- {
- final Entry oldEntry = ec.getEntry(entry.getName());
- ec.replaceEntry(oldEntry, entry, null);
- }
- else
- {
- reader.rejectLastEntry(WARN_IMPORT_ENTRY_EXISTS.get());
- }
- break;
- case NO_SUCH_OBJECT:
- reader.rejectLastEntry(ERR_IMPORT_PARENT_NOT_FOUND.get(dn.parent()));
- break;
- default:
- // Not sure why it failed.
- reader.rejectLastEntry(e.getMessageObject());
- break;
- }
- }
- }
- final long finishTime = System.currentTimeMillis();
-
- waitForShutdown(timerService);
-
- final long importTime = finishTime - startTime;
- float rate = 0;
- if (importTime > 0)
- {
- rate = 1000f * reader.getEntriesRead() / importTime;
- }
- logger.info(NOTE_IMPORT_FINAL_STATUS, reader.getEntriesRead(), importCount, reader.getEntriesIgnored(),
- reader.getEntriesRejected(), 0, importTime / 1000, rate);
- return new LDIFImportResult(reader.getEntriesRead(), reader.getEntriesRejected(), reader.getEntriesIgnored());
- }
- finally
- {
- close();
-
- // if not already stopped, then stop it
- waitForShutdown(timerService);
- }
- }
- catch (DirectoryException e)
- {
- logger.traceException(e);
- throw e;
- }
- catch (OpenDsException e)
- {
- logger.traceException(e);
- throw new DirectoryException(getServerErrorResultCode(), e.getMessageObject());
- }
- catch (Exception e)
- {
- logger.traceException(e);
- throw new DirectoryException(getServerErrorResultCode(), LocalizableMessage.raw(e.getMessage()));
- }
- }
-
- private void waitForShutdown(ScheduledThreadPoolExecutor timerService) throws InterruptedException
- {
- timerService.shutdown();
- timerService.awaitTermination(20, TimeUnit.SECONDS);
- }
-
- private LDIFImportResult importLDIFWithOnDiskMerge(final LDIFImportConfig importConfig, ServerContext serverContext)
- throws DirectoryException
- {
- try
- {
- return new Importer(this, importConfig, config, serverContext).processImport();
- }
- catch (DirectoryException e)
- {
- logger.traceException(e);
- throw e;
- }
- catch (OpenDsException e)
- {
- logger.traceException(e);
- throw new DirectoryException(getServerErrorResultCode(), e.getMessageObject(), e);
- }
- catch (Exception e)
- {
- logger.traceException(e);
- throw new DirectoryException(getServerErrorResultCode(),
- LocalizableMessage.raw(stackTraceToSingleLineString(e)), e);
- }
+ //TODO JNR may call new SuccessiveAddsImportStrategy() depending on configured import strategy
+ return new Importer.StrategyImpl(config);
}
/**
@@ -391,15 +199,11 @@
*/
void registerEntryContainer(DN baseDN, EntryContainer entryContainer) throws InitializationException
{
- EntryContainer ec1 = this.entryContainers.get(baseDN);
-
- // If an entry container for this baseDN is already open we don't allow
- // another to be opened.
- if (ec1 != null)
+ EntryContainer ec = this.entryContainers.get(baseDN);
+ if (ec != null)
{
- throw new InitializationException(ERR_ENTRY_CONTAINER_ALREADY_REGISTERED.get(ec1.getTreePrefix(), baseDN));
+ throw new InitializationException(ERR_ENTRY_CONTAINER_ALREADY_REGISTERED.get(ec.getTreePrefix(), baseDN));
}
-
this.entryContainers.put(baseDN, entryContainer);
}
@@ -432,7 +236,7 @@
}
}
- nextid = new AtomicLong(highestID.longValue() + 1);
+ nextEntryID = new AtomicLong(highestID.longValue() + 1);
}
/**
@@ -470,7 +274,6 @@
String monitorName = backend.getBackendID() + " Storage";
monitor = new BackendMonitor(monitorName, this);
}
-
return monitor;
}
@@ -503,8 +306,7 @@
// Sort the list in order of priority.
Collections.sort(trees, new TreePreloadComparator());
- // Preload each tree until we reach the time limit or the cache
- // is filled.
+ // Preload each tree until we reach the time limit or the cache is filled.
try
{
throw new UnsupportedOperationException("Not implemented exception");
@@ -638,7 +440,7 @@
*/
EntryID getNextEntryID()
{
- return new EntryID(nextid.getAndIncrement());
+ return new EntryID(nextEntryID.getAndIncrement());
}
/**
@@ -647,7 +449,7 @@
*/
public void resetNextEntryID()
{
- nextid.set(1);
+ nextEntryID.set(1);
}
/** {@inheritDoc} */
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/SuccessiveAddsImportStrategy.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/SuccessiveAddsImportStrategy.java
new file mode 100644
index 0000000..fd0fb1d
--- /dev/null
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/SuccessiveAddsImportStrategy.java
@@ -0,0 +1,222 @@
+/*
+ * 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
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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 2015 ForgeRock AS
+ */
+package org.opends.server.backends.pluggable;
+
+import static org.opends.messages.BackendMessages.*;
+import static org.opends.messages.UtilityMessages.*;
+import static org.opends.server.core.DirectoryServer.*;
+import static org.opends.server.util.StaticUtils.*;
+
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.ServerContext;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
+import org.opends.server.types.LDIFImportConfig;
+import org.opends.server.types.LDIFImportResult;
+import org.opends.server.types.OpenDsException;
+import org.opends.server.util.LDIFException;
+import org.opends.server.util.LDIFReader;
+
+/**
+ * Imports LDIF entries one by one, by calling
+ * {@link EntryContainer#addEntry(Entry, org.opends.server.core.AddOperation)}.
+ */
+final class SuccessiveAddsImportStrategy implements ImportStrategy
+{
+ /** Logs the progress of the import. */
+ private static final class ImportProgress implements Runnable
+ {
+ private final LDIFReader reader;
+ private long previousCount;
+ private long previousTime;
+
+ public ImportProgress(LDIFReader reader)
+ {
+ this.reader = reader;
+ }
+
+ @Override
+ public void run()
+ {
+ long latestCount = reader.getEntriesRead() + 0;
+ long deltaCount = latestCount - previousCount;
+ long latestTime = System.currentTimeMillis();
+ long deltaTime = latestTime - previousTime;
+ if (deltaTime == 0)
+ {
+ return;
+ }
+ long entriesRead = reader.getEntriesRead();
+ long entriesIgnored = reader.getEntriesIgnored();
+ long entriesRejected = reader.getEntriesRejected();
+ float rate = 1000f * deltaCount / deltaTime;
+ logger.info(NOTE_IMPORT_PROGRESS_REPORT, entriesRead, entriesIgnored, entriesRejected, rate);
+
+ previousCount = latestCount;
+ previousTime = latestTime;
+ }
+ }
+
+ private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
+
+ private static final int IMPORT_PROGRESS_INTERVAL = 10000;
+
+ /** {@inheritDoc} */
+ @Override
+ public LDIFImportResult importLDIF(LDIFImportConfig importConfig, RootContainer rootContainer,
+ ServerContext serverContext) throws DirectoryException
+ {
+ try
+ {
+ ScheduledThreadPoolExecutor timerService = new ScheduledThreadPoolExecutor(1);
+ try
+ {
+ final LDIFReader reader;
+ try
+ {
+ reader = new LDIFReader(importConfig);
+ }
+ catch (Exception e)
+ {
+ LocalizableMessage m = ERR_LDIF_BACKEND_CANNOT_CREATE_LDIF_READER.get(stackTraceToSingleLineString(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m, e);
+ }
+
+ long importCount = 0;
+ final long startTime = System.currentTimeMillis();
+ timerService.scheduleAtFixedRate(new ImportProgress(reader),
+ IMPORT_PROGRESS_INTERVAL, IMPORT_PROGRESS_INTERVAL, TimeUnit.MILLISECONDS);
+ while (true)
+ {
+ final Entry entry;
+ try
+ {
+ entry = reader.readEntry();
+ if (entry == null)
+ {
+ break;
+ }
+ }
+ catch (LDIFException le)
+ {
+ if (!le.canContinueReading())
+ {
+ LocalizableMessage m = ERR_LDIF_BACKEND_ERROR_READING_LDIF.get(stackTraceToSingleLineString(le));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m, le);
+ }
+ continue;
+ }
+
+ final DN dn = entry.getName();
+ final EntryContainer ec = rootContainer.getEntryContainer(dn);
+ if (ec == null)
+ {
+ final LocalizableMessage m = ERR_LDIF_SKIP.get(dn);
+ logger.error(m);
+ reader.rejectLastEntry(m);
+ continue;
+ }
+
+ try
+ {
+ ec.addEntry(entry, null);
+ importCount++;
+ }
+ catch (DirectoryException e)
+ {
+ switch (e.getResultCode().asEnum())
+ {
+ case ENTRY_ALREADY_EXISTS:
+ if (importConfig.replaceExistingEntries())
+ {
+ final Entry oldEntry = ec.getEntry(entry.getName());
+ ec.replaceEntry(oldEntry, entry, null);
+ }
+ else
+ {
+ reader.rejectLastEntry(WARN_IMPORT_ENTRY_EXISTS.get());
+ }
+ break;
+ case NO_SUCH_OBJECT:
+ reader.rejectLastEntry(ERR_IMPORT_PARENT_NOT_FOUND.get(dn.parent()));
+ break;
+ default:
+ // Not sure why it failed.
+ reader.rejectLastEntry(e.getMessageObject());
+ break;
+ }
+ }
+ }
+ final long finishTime = System.currentTimeMillis();
+
+ waitForShutdown(timerService);
+
+ final long importTime = finishTime - startTime;
+ float rate = 0;
+ if (importTime > 0)
+ {
+ rate = 1000f * reader.getEntriesRead() / importTime;
+ }
+ logger.info(NOTE_IMPORT_FINAL_STATUS, reader.getEntriesRead(), importCount, reader.getEntriesIgnored(),
+ reader.getEntriesRejected(), 0, importTime / 1000, rate);
+ return new LDIFImportResult(reader.getEntriesRead(), reader.getEntriesRejected(), reader.getEntriesIgnored());
+ }
+ finally
+ {
+ rootContainer.close();
+
+ // if not already stopped, then stop it
+ waitForShutdown(timerService);
+ }
+ }
+ catch (DirectoryException e)
+ {
+ logger.traceException(e);
+ throw e;
+ }
+ catch (OpenDsException e)
+ {
+ logger.traceException(e);
+ throw new DirectoryException(getServerErrorResultCode(), e.getMessageObject());
+ }
+ catch (Exception e)
+ {
+ logger.traceException(e);
+ throw new DirectoryException(getServerErrorResultCode(), LocalizableMessage.raw(e.getMessage()));
+ }
+ }
+
+ private void waitForShutdown(ScheduledThreadPoolExecutor timerService) throws InterruptedException
+ {
+ timerService.shutdown();
+ timerService.awaitTermination(20, TimeUnit.SECONDS);
+ }
+}
--
Gitblit v1.10.0