From 71ee88697d285e8932a8dcab3ebc27c79387dd68 Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Mon, 08 Jun 2015 07:58:39 +0000
Subject: [PATCH] OPENDJ-2085 CR-7159 NullPointerException while importing data in an instance containing 2 backends
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Suffix.java | 14 ++++++
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java | 51 ++++++++-----------------
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeStorageImporter.java | 17 +++++---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeBufferImporter.java | 17 +++++---
4 files changed, 52 insertions(+), 47 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
index 32eda1c..029d139 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
@@ -2638,28 +2638,22 @@
* Sets a new tree prefix for this entry container and rename all
* existing trees in use by this entry container.
*
+ * @param txn the transaction for renaming Trees
* @param newBaseDN The new tree prefix to use.
* @throws StorageRuntimeException If an error occurs in the storage.
*/
- void setTreePrefix(final String newBaseDN) throws StorageRuntimeException
+ void setTreePrefix(WriteableTransaction txn, final String newBaseDN) throws StorageRuntimeException
{
final List<Tree> allTrees = listTrees();
try
{
// Rename in transaction.
- storage.write(new WriteOperation()
+ for(Tree tree : allTrees)
{
- @Override
- public void run(WriteableTransaction txn) throws Exception
- {
- for(Tree tree : allTrees)
- {
- TreeName oldName = tree.getName();
- TreeName newName = oldName.replaceBaseDN(newBaseDN);
- txn.renameTree(oldName, newName);
- }
- }
- });
+ TreeName oldName = tree.getName();
+ TreeName newName = oldName.replaceBaseDN(newBaseDN);
+ txn.renameTree(oldName, newName);
+ }
// Only rename the containers if the txn succeeded.
for (Tree tree : allTrees)
{
@@ -2677,32 +2671,21 @@
}
throw new StorageRuntimeException(ERR_UNCHECKED_EXCEPTION.get(msg).toString(), e);
}
- finally
+ try
{
- try
+ for(Tree tree : allTrees)
{
- storage.write(new WriteOperation()
- {
- @Override
- public void run(WriteableTransaction txn) throws Exception
- {
- // Open the containers backup.
- for(Tree tree : allTrees)
- {
- tree.open(txn);
- }
- }
- });
+ tree.open(txn);
}
- catch (Exception e)
+ }
+ catch (Exception e)
+ {
+ String msg = e.getMessage();
+ if (msg == null)
{
- String msg = e.getMessage();
- if (msg == null)
- {
- msg = stackTraceToSingleLineString(e);
- }
- throw new StorageRuntimeException(ERR_UNCHECKED_EXCEPTION.get(msg).toString(), e);
+ msg = stackTraceToSingleLineString(e);
}
+ throw new StorageRuntimeException(ERR_UNCHECKED_EXCEPTION.get(msg).toString(), e);
}
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeBufferImporter.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeBufferImporter.java
index 3ecf080..c671611 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeBufferImporter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeBufferImporter.java
@@ -696,7 +696,11 @@
sourceEntryContainer = entryContainer;
// Create a temp entry container
- DN tempDN = baseDN.child(DN.valueOf("dc=importTmp"));
+ DN tempDN = DN.valueOf(baseDN.rdn() + "_importTmp");
+ if (baseDN.size() > 1)
+ {
+ tempDN = baseDN.parent().child(tempDN);
+ }
entryContainer = rootContainer.openEntryContainer(tempDN, txn);
}
}
@@ -916,11 +920,12 @@
{
for (Suffix suffix : dnSuffixMap.values())
{
- DN baseDN = suffix.getBaseDN();
- EntryContainer entryContainer = suffix.getSrcEntryContainer();
- if (entryContainer != null)
+ final EntryContainer toDelete = suffix.getSrcEntryContainer();
+ if (toDelete != null)
{
- final EntryContainer toDelete = rootContainer.unregisterEntryContainer(baseDN);
+ final DN baseDN = toDelete.getBaseDN();
+
+ rootContainer.unregisterEntryContainer(baseDN);
toDelete.lock();
toDelete.close();
toDelete.delete(txn);
@@ -928,7 +933,7 @@
final EntryContainer replacement = suffix.getEntryContainer();
replacement.lock();
- replacement.setTreePrefix(baseDN.toNormalizedUrlSafeString());
+ replacement.setTreePrefix(txn, baseDN.toNormalizedUrlSafeString());
replacement.unlock();
rootContainer.registerEntryContainer(baseDN, replacement);
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeStorageImporter.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeStorageImporter.java
index 85df3ff..66bf17a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeStorageImporter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeStorageImporter.java
@@ -1470,7 +1470,11 @@
sourceEntryContainer = entryContainer;
// Create a temp entry container
- DN tempDN = baseDN.child(DN.valueOf("dc=importTmp"));
+ DN tempDN = DN.valueOf(baseDN.rdn() + "_importTmp");
+ if (baseDN.size() > 1)
+ {
+ tempDN = baseDN.parent().child(tempDN);
+ }
entryContainer = rootContainer.openEntryContainer(tempDN, txn);
}
}
@@ -1605,11 +1609,12 @@
{
for (Suffix suffix : dnSuffixMap.values())
{
- DN baseDN = suffix.getBaseDN();
- EntryContainer entryContainer = suffix.getSrcEntryContainer();
- if (entryContainer != null)
+ final EntryContainer toDelete = suffix.getSrcEntryContainer();
+ if (toDelete != null)
{
- final EntryContainer toDelete = rootContainer.unregisterEntryContainer(baseDN);
+ final DN baseDN = toDelete.getBaseDN();
+
+ rootContainer.unregisterEntryContainer(baseDN);
toDelete.lock();
toDelete.close();
toDelete.delete(txn);
@@ -1617,7 +1622,7 @@
final EntryContainer replacement = suffix.getEntryContainer();
replacement.lock();
- replacement.setTreePrefix(baseDN.toNormalizedUrlSafeString());
+ replacement.setTreePrefix(txn, baseDN.toNormalizedUrlSafeString());
replacement.unlock();
rootContainer.registerEntryContainer(baseDN, replacement);
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Suffix.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Suffix.java
index 3ec0521..42b2539 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Suffix.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/Suffix.java
@@ -53,7 +53,19 @@
private final List<DN> includeBranches, excludeBranches;
private final DN baseDN;
+ /**
+ * If not null this is the original entry container for the suffix in the backend before the
+ * import begins.
+ * <p>
+ * Then its data is completely deleted only at the very end of the import when calling
+ * *Importer.switchEntryContainers().
+ */
private final EntryContainer srcEntryContainer;
+ /**
+ * If {@link #srcEntryContainer} is null, it is the original entry container for the suffix in the
+ * backend. Otherwise it is a temporary entry container that will eventually replace the existing
+ * {@link #srcEntryContainer} at the end of the import.
+ */
private final EntryContainer entryContainer;
private final Object synchObject = new Object();
private static final int PARENT_ID_SET_SIZE = 16 * 1024;
@@ -78,7 +90,7 @@
{
this.entryContainer = entryContainer;
this.srcEntryContainer = srcEntryContainer;
- this.baseDN = entryContainer.getBaseDN();
+ this.baseDN = srcEntryContainer != null ? srcEntryContainer.getBaseDN() : entryContainer.getBaseDN();
if (includeBranches != null)
{
this.includeBranches = includeBranches;
--
Gitblit v1.10.0