From 76159518846a6aee0d205624b00f93a83f4aeff2 Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Wed, 17 Jun 2015 09:49:32 +0000
Subject: [PATCH] OPENDJ-2148 CR-7287 "NullPointerException" when running import-ldif online with exclude branch

---
 opendj-server-legacy/src/messages/org/opends/messages/backend.properties                                  |    4 +++-
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java                  |    6 ++++++
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeStorageImporter.java   |    6 +++---
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeBufferImporter.java    |    6 +++---
 opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java |    2 ++
 opendj-server-legacy/src/main/java/org/opends/server/api/Backend.java                                     |   16 ++++++++++++++++
 6 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/api/Backend.java b/opendj-server-legacy/src/main/java/org/opends/server/api/Backend.java
index 159926e..168fecf 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/api/Backend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/api/Backend.java
@@ -975,6 +975,22 @@
   }
 
   /**
+   * Returns if <tt>exclude</tt> contains at least a DN or <tt>include</tt> contains anything else than one of
+   * <tt>baseDNs</tt>.
+   *
+   * @param baseDNs the baseDNs of a backend
+   * @param includeBranches a set of include DNs
+   * @param excludeBranches a set of exclude DNs
+   * @return true if <tt>exclude</tt> contains at least a DN or <tt>include</tt> contains anything else than one of
+   *         <tt>baseDNs</tt>
+   */
+  public static boolean importIncludesOrExcludesBranches(Collection<DN> baseDNs, Collection<DN> includeBranches,
+      Collection<DN> excludeBranches)
+  {
+    return !excludeBranches.isEmpty() || includeBranches.size() != 1 || !baseDNs.containsAll(includeBranches);
+  }
+
+  /**
    * Indicates whether a backend should be used to handle operations
    * for the provided entry given the set of base DNs and exclude DNs.
    *
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java
index c1567c0..e27d70c 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendImpl.java
@@ -664,6 +664,12 @@
     {
       throw new DirectoryException(getServerErrorResultCode(), ERR_IMPORT_BACKEND_ONLINE.get());
     }
+    if (importIncludesOrExcludesBranches(cfg.getBaseDN(), importConfig.getIncludeBranches(),
+        importConfig.getExcludeBranches()))
+    {
+      // fail-fast to avoid ending up in an unrecoverable state for the server
+      throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, ERR_IMPORT_UNSUPPORTED_WITH_BRANCH.get());
+    }
 
     try
     {
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 7a7b1fb..63320dc 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
@@ -97,6 +97,7 @@
 import org.opends.server.admin.std.server.BackendIndexCfg;
 import org.opends.server.admin.std.server.PDBBackendCfg;
 import org.opends.server.admin.std.server.PluggableBackendCfg;
+import org.opends.server.api.Backend;
 import org.opends.server.backends.RebuildConfig;
 import org.opends.server.backends.RebuildConfig.RebuildMode;
 import org.opends.server.backends.pdb.PDBStorage;
@@ -682,9 +683,8 @@
         }
       }
 
-      if (excludeBranches.isEmpty()
-          && includeBranches.size() == 1
-          && includeBranches.get(0).equals(baseDN))
+      if (!Backend.importIncludesOrExcludesBranches(Collections.singleton(baseDN), includeBranches, excludeBranches))
+
       {
         // This entire base DN is explicitly included in the import with
         // no exclude branches that we need to migrate.
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 66bf17a..20b86ef 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
@@ -48,6 +48,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -84,6 +85,7 @@
 import org.opends.server.admin.std.meta.BackendIndexCfgDefn.IndexType;
 import org.opends.server.admin.std.server.BackendIndexCfg;
 import org.opends.server.admin.std.server.PluggableBackendCfg;
+import org.opends.server.api.Backend;
 import org.opends.server.backends.pluggable.AttributeIndex.MatchingRuleIndex;
 import org.opends.server.backends.pluggable.ImportLDIFReader.EntryInformation;
 import org.opends.server.backends.pluggable.OnDiskMergeBufferImporter.DNCache;
@@ -1456,9 +1458,7 @@
         }
       }
 
-      if (excludeBranches.isEmpty()
-          && includeBranches.size() == 1
-          && includeBranches.get(0).equals(baseDN))
+      if (!Backend.importIncludesOrExcludesBranches(Collections.singleton(baseDN), includeBranches, excludeBranches))
       {
         // This entire base DN is explicitly included in the import with
         // no exclude branches that we need to migrate.
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/backend.properties b/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
index 82db2cd..837e2d2 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
@@ -1335,4 +1335,6 @@
 WARN_BACKUPDB_INCREMENTAL_NOT_FOUND_DOING_NORMAL_578=Could not find any \
  backup in '%s'. A full backup will be executed
 ERR_VERIFY_BACKEND_ONLINE_579=The backend must be disabled before \
- verification process can start
\ No newline at end of file
+ verification process can start
+ERR_IMPORT_UNSUPPORTED_WITH_BRANCH_580=Import operation is not supported \
+ when exclude or include sub-branches have been specified
\ No newline at end of file
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
index 03d8581..8299a83 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/PluggableBackendImplTestCase.java
@@ -40,6 +40,7 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Random;
 
@@ -898,6 +899,7 @@
       importConf.setInvokeImportPlugins(true);
       importConf.setClearBackend(true);
       importConf.writeRejectedEntries(rejectedEntries);
+      importConf.setIncludeBranches(Collections.singleton(testBaseDN));
       backend.importLDIF(importConf, DirectoryServer.getInstance().getServerContext());
     }
     assertEquals(rejectedEntries.size(), 0, "No entries should be rejected");

--
Gitblit v1.10.0