From ee0fbff002e17a56aca09cb8dc7da0f4fe20ad6e Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Tue, 31 Jul 2007 21:38:45 +0000
Subject: [PATCH] 

---
 opends/src/server/org/opends/server/backends/jeb/VLVIndex.java                              |   16 +
 opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestImportAndExport.java  |  221 ++++++++++++++------
 opends/src/server/org/opends/server/messages/JebMessages.java                               |    7 
 opends/tests/unit-tests-testng/src/server/org/opends/server/tools/ImportLDIFTestCase.java   |   36 +++
 opends/src/server/org/opends/server/backends/jeb/ImportJob.java                             |   12 
 opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java |  102 ++++++++
 opends/src/admin/defn/org/opends/server/admin/std/VLVJEIndexConfiguration.xml               |    6 
 opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java                        |    2 
 opends/src/server/org/opends/server/tasks/ImportTask.java                                   |  214 ++++++++++++++-----
 opends/src/server/org/opends/server/tools/ImportLDIF.java                                   |   29 -
 10 files changed, 489 insertions(+), 156 deletions(-)

diff --git a/opends/src/admin/defn/org/opends/server/admin/std/VLVJEIndexConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/VLVJEIndexConfiguration.xml
index fe0824c..9e3334c 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/VLVJEIndexConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/VLVJEIndexConfiguration.xml
@@ -94,10 +94,10 @@
             Search the base object only.
           </adm:synopsis>
         </adm:value>
-        <adm:value name="single-object">
+        <adm:value name="single-level">
           <adm:synopsis>
-            Search subordinate objects to the base object but not include
-            the base object itself.
+            Search immediate children of the base object but not include
+            any of their descendants and the base object itself.
           </adm:synopsis>
         </adm:value>
         <adm:value name="subordinate-subtree">
diff --git a/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java b/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
index 5cdbe74..b0b0571 100644
--- a/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
+++ b/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -273,7 +273,7 @@
    * Close the attribute index.
    *
    * @throws DatabaseException if a JE database error occurs while
-   * openning the index.
+   * closing the index.
    */
   public void close() throws DatabaseException
   {
diff --git a/opends/src/server/org/opends/server/backends/jeb/ImportJob.java b/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
index 67cc08e..f53fdbc 100644
--- a/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
+++ b/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
@@ -1090,8 +1090,10 @@
         }
 
         // Remove any overlapping include branches.
-        for(DN includeDN : includeBranches)
+        Iterator<DN> includeBranchIterator = includeBranches.iterator();
+        while(includeBranchIterator.hasNext())
         {
+          DN includeDN = includeBranchIterator.next();
           boolean keep = true;
           for(DN dn : includeBranches)
           {
@@ -1103,15 +1105,17 @@
           }
           if(!keep)
           {
-            includeBranches.remove(includeDN);
+            includeBranchIterator.remove();
           }
         }
 
         // Remvoe any exclude branches that are not are not under a include
         // branch since they will be migrated as part of the existing entries
         // outside of the include branches anyways.
-        for(DN excludeDN : excludeBranches)
+        Iterator<DN> excludeBranchIterator = excludeBranches.iterator();
+        while(excludeBranchIterator.hasNext())
         {
+          DN excludeDN = excludeBranchIterator.next();
           boolean keep = false;
           for(DN includeDN : includeBranches)
           {
@@ -1123,7 +1127,7 @@
           }
           if(!keep)
           {
-            excludeBranches.remove(excludeDN);
+            excludeBranchIterator.remove();
           }
         }
 
diff --git a/opends/src/server/org/opends/server/backends/jeb/VLVIndex.java b/opends/src/server/org/opends/server/backends/jeb/VLVIndex.java
index a6c983d..ee1aa41 100644
--- a/opends/src/server/org/opends/server/backends/jeb/VLVIndex.java
+++ b/opends/src/server/org/opends/server/backends/jeb/VLVIndex.java
@@ -254,6 +254,7 @@
     }
 
     this.count = new AtomicInteger(0);
+    this.config.addChangeListener(this);
   }
 
   /**
@@ -286,6 +287,18 @@
   }
 
   /**
+   * Close the VLV index.
+   *
+   * @throws DatabaseException if a JE database error occurs while
+   * closing the index.
+   */
+  public void close() throws DatabaseException
+  {
+    super.close();
+    this.config.removeChangeListener(this);
+  }
+
+  /**
    * Update the vlvIndex for a new entry.
    *
    * @param txn A database transaction, or null if none is required.
@@ -1431,6 +1444,9 @@
     if(adminActionRequired)
     {
       trusted = false;
+      int msgID = MSGID_JEB_INDEX_ADD_REQUIRES_REBUILD;
+      String message = getMessage(msgID, name);
+      messages.add(message);
       try
       {
         state.putIndexTrustState(null, this, false);
diff --git a/opends/src/server/org/opends/server/messages/JebMessages.java b/opends/src/server/org/opends/server/messages/JebMessages.java
index 8c6f184..008a97e 100644
--- a/opends/src/server/org/opends/server/messages/JebMessages.java
+++ b/opends/src/server/org/opends/server/messages/JebMessages.java
@@ -1603,12 +1603,13 @@
                     "index entry limit in index %s. This index must be " +
                     "rebuilt before it can use the new limit");
     registerMessage(MSGID_JEB_INDEX_ADD_REQUIRES_REBUILD,
-                    "Index %s is currently operating in a degraded read-only " +
-                    "state and must be rebuilt before it can used");
+                    "Due to changes in the configuration, index %s is " +
+                    "currently operating in a degraded state and must be " +
+                    "rebuilt before it can used");
     registerMessage(MSGID_JEB_INDEX_CORRUPT_REQUIRES_REBUILD,
                     "An error occurred while reading from index %s. The " +
                     "index seems to be corrupt and is now operating in " +
-                    "a degraded read-only state. The index must be rebuilt " +
+                    "a degraded state. The index must be rebuilt " +
                     "before it can return to normal operation");
     registerMessage(MSGID_JEB_IMPORT_BACKEND_ONLINE,
                     "The backend must be disabled before the import process" +
diff --git a/opends/src/server/org/opends/server/tasks/ImportTask.java b/opends/src/server/org/opends/server/tasks/ImportTask.java
index a0b2901..e2615ce 100644
--- a/opends/src/server/org/opends/server/tasks/ImportTask.java
+++ b/opends/src/server/org/opends/server/tasks/ImportTask.java
@@ -224,19 +224,8 @@
     clearBackend = TaskUtils.getBoolean(attrList, false);
 
     // Make sure that either the "includeBranchStrings" argument or the
-    // "backendID" argument was provided, but not both.
-    if(!includeBranchStrings.isEmpty())
-    {
-      if(backendID != null)
-      {
-        int    msgID   = MSGID_LDIFIMPORT_CONFLICTING_OPTIONS;
-        String message = getMessage(msgID, typeIncludeBranch.getNameOrOID(),
-                                    typeBackendID.getNameOrOID());
-        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
-                                     msgID);
-      }
-    }
-    else if(backendID == null)
+    // "backendID" argument was provided.
+    if(includeBranchStrings.isEmpty() && backendID == null)
     {
       int    msgID   = MSGID_LDIFIMPORT_MISSING_BACKEND_ARGUMENT;
       String message = getMessage(msgID, typeIncludeBranch.getNameOrOID(),
@@ -245,15 +234,109 @@
                                    msgID);
     }
 
+    Backend backend = null;
+    ArrayList<DN> defaultIncludeBranches;
+    ArrayList<DN> excludeBranches =
+        new ArrayList<DN>(excludeBranchStrings.size());
+    ArrayList<DN> includeBranches =
+        new ArrayList<DN>(includeBranchStrings.size());
+
+    for (String s : includeBranchStrings)
+    {
+      DN includeBranch;
+      try
+      {
+        includeBranch = DN.decode(s);
+      }
+      catch (DirectoryException de)
+      {
+        int    msgID   = MSGID_LDIFIMPORT_CANNOT_DECODE_INCLUDE_BASE;
+        String message = getMessage(msgID, s, de.getErrorMessage());
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                     msgID);
+      }
+      catch (Exception e)
+      {
+        int    msgID   = MSGID_LDIFIMPORT_CANNOT_DECODE_INCLUDE_BASE;
+        String message = getMessage(msgID, s, getExceptionMessage(e));
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                     msgID);
+      }
+
+      if(! includeBranches.contains(includeBranch))
+      {
+        includeBranches.add(includeBranch);
+      }
+    }
+    for (String s : excludeBranchStrings)
+    {
+      DN excludeBranch;
+      try
+      {
+        excludeBranch = DN.decode(s);
+      }
+      catch (DirectoryException de)
+      {
+        int    msgID   = MSGID_LDIFIMPORT_CANNOT_DECODE_EXCLUDE_BASE;
+        String message = getMessage(msgID, s, de.getErrorMessage());
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                     msgID);
+      }
+      catch (Exception e)
+      {
+        int    msgID   = MSGID_LDIFIMPORT_CANNOT_DECODE_EXCLUDE_BASE;
+        String message = getMessage(msgID, s, getExceptionMessage(e));
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                     msgID);
+      }
+
+      if (! excludeBranches.contains(excludeBranch))
+      {
+        excludeBranches.add(excludeBranch);
+      }
+    }
+
+    for (String filterString : excludeFilterStrings)
+    {
+      try
+      {
+        SearchFilter.createFilterFromString(filterString);
+      }
+      catch (DirectoryException de)
+      {
+        int    msgID   = MSGID_LDIFIMPORT_CANNOT_PARSE_EXCLUDE_FILTER;
+        String message = getMessage(msgID, filterString,
+                                    de.getErrorMessage());
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                     msgID);
+      }
+    }
+
+    for (String filterString : includeFilterStrings)
+    {
+      try
+      {
+        SearchFilter.createFilterFromString(filterString);
+      }
+      catch (DirectoryException de)
+      {
+        int    msgID   = MSGID_LDIFIMPORT_CANNOT_PARSE_INCLUDE_FILTER;
+        String message = getMessage(msgID, filterString,
+                                    de.getErrorMessage());
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                     msgID);
+      }
+    }
+
     if(backendID != null)
     {
-      Backend backend = DirectoryServer.getBackend(backendID);
+      backend = DirectoryServer.getBackend(backendID);
       if (backend == null)
       {
         int    msgID   = MSGID_LDIFIMPORT_NO_BACKENDS_FOR_ID;
         String message = getMessage(msgID, backendID);
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
-                                   msgID);
+                                     msgID);
       }
       else if (! backend.supportsLDIFImport())
       {
@@ -262,11 +345,12 @@
         throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
                                      msgID);
       }
-      // Make sure that if the "backendID" argument was provided and the
-      // "append" option was not provided, the "clearBackend" argument was also
-      // provided if there are more then one baseDNs for the backend being
-      // imported.
-      else if(!append && backend.getBaseDNs().length > 1 && !clearBackend)
+      // Make sure that if the "backendID" argument was provided, no include
+      // base was included, and the "append" ption was not provided, the
+      // "clearBackend" argument was also provided if there are more then one
+      // baseDNs for the backend being imported.
+      else if(!append && includeBranchStrings.isEmpty() &&
+          backend.getBaseDNs().length > 1 && !clearBackend)
       {
         StringBuilder builder = new StringBuilder();
         for(DN dn : backend.getBaseDNs())
@@ -284,31 +368,8 @@
     else
     {
       // Find the backend that includes all the branches.
-      Backend backend = null;
-      for (String s : includeBranchStrings)
+      for(DN includeBranch : includeBranches)
       {
-        DN includeBranch;
-        try
-        {
-          includeBranch = DN.decode(s);
-        }
-        catch (DirectoryException de)
-        {
-          int    msgID   = MSGID_LDIFIMPORT_CANNOT_DECODE_INCLUDE_BASE;
-          String message = getMessage(msgID, s, de.getErrorMessage());
-          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
-                   message, msgID);
-          throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
-                                       msgID);
-        }
-        catch (Exception e)
-        {
-          int    msgID   = MSGID_LDIFIMPORT_CANNOT_DECODE_INCLUDE_BASE;
-          String message = getMessage(msgID, s, getExceptionMessage(e));
-          throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
-                                       msgID);
-        }
-
         Backend locatedBackend = DirectoryServer.getBackend(includeBranch);
         if(locatedBackend != null)
         {
@@ -320,13 +381,35 @@
           {
             // The include branches span across multiple backends.
             int    msgID   = MSGID_LDIFIMPORT_INVALID_INCLUDE_BASE;
-            String message = getMessage(msgID, s, backend.getBackendID());
+            String message = getMessage(msgID,
+                                        includeBranch.toNormalizedString(),
+                                        backend.getBackendID());
             throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
                                          message, msgID);
           }
         }
       }
     }
+
+    // Make sure the selected backend will handle all the include branches
+    defaultIncludeBranches = new ArrayList<DN>(backend.getBaseDNs().length);
+    for (DN dn : backend.getBaseDNs())
+    {
+      defaultIncludeBranches.add(dn);
+    }
+
+    for(DN includeBranch : includeBranches)
+    {
+      if (! Backend.handlesEntry(includeBranch, defaultIncludeBranches,
+                                 excludeBranches))
+      {
+        int    msgID   = MSGID_LDIFIMPORT_INVALID_INCLUDE_BASE;
+        String message = getMessage(msgID, includeBranch.toNormalizedString(),
+                                    backend.getBackendID());
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message,
+                                     msgID);
+      }
+    }
   }
 
 
@@ -408,11 +491,11 @@
     // Get the backend into which the LDIF should be imported.
     Backend       backend = null;
     ArrayList<DN> defaultIncludeBranches;
-    ArrayList<DN> excludeBranches = new ArrayList<DN>();
-    ArrayList<DN> includeBranches = new ArrayList<DN>();
+    ArrayList<DN> excludeBranches =
+        new ArrayList<DN>(excludeBranchStrings.size());
+    ArrayList<DN> includeBranches =
+        new ArrayList<DN>(includeBranchStrings.size());
 
-
-    includeBranches = new ArrayList<DN>(includeBranchStrings.size());
     for (String s : includeBranchStrings)
     {
       DN includeBranch;
@@ -437,7 +520,10 @@
         return TaskState.STOPPED_BY_ERROR;
       }
 
-      includeBranches.add(includeBranch);
+      if(! includeBranches.contains(includeBranch))
+      {
+        includeBranches.add(includeBranch);
+      }
     }
 
     if(backendID != null)
@@ -460,11 +546,12 @@
                  message, msgID);
         return TaskState.STOPPED_BY_ERROR;
       }
-      // Make sure that if the "backendID" argument was provided and the
-      // "append" option was not provided, the "clearBackend" argument was also
-      // provided if there are more then one baseDNs for the backend being
-      // imported.
-      else if(!append && backend.getBaseDNs().length > 1 && !clearBackend)
+      // Make sure that if the "backendID" argument was provided, no include
+      // base was included, and the "append" ption was not provided, the
+      // "clearBackend" argument was also provided if there are more then one
+      // baseDNs for the backend being imported.
+      else if(!append && includeBranches.isEmpty() &&
+          backend.getBaseDNs().length > 1 && !clearBackend)
       {
         StringBuilder builder = new StringBuilder();
         builder.append(backend.getBaseDNs()[0].toNormalizedString());
@@ -574,6 +661,23 @@
     {
       includeBranches = defaultIncludeBranches;
     }
+    else
+    {
+      // Make sure the selected backend will handle all the include branches
+      for(DN includeBranch : includeBranches)
+      {
+        if (! Backend.handlesEntry(includeBranch, defaultIncludeBranches,
+                                   excludeBranches))
+        {
+          int    msgID   = MSGID_LDIFIMPORT_INVALID_INCLUDE_BASE;
+          String message = getMessage(msgID, includeBranch.toNormalizedString(),
+                                      backend.getBackendID());
+          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
+                   message, msgID);
+          return TaskState.STOPPED_BY_ERROR;
+        }
+      }
+    }
 
     // Create the LDIF import configuration to use when reading the LDIF.
     ArrayList<String> fileList = new ArrayList<String>(ldifFiles);
diff --git a/opends/src/server/org/opends/server/tools/ImportLDIF.java b/opends/src/server/org/opends/server/tools/ImportLDIF.java
index 8f3b9dd..1b60234 100644
--- a/opends/src/server/org/opends/server/tools/ImportLDIF.java
+++ b/opends/src/server/org/opends/server/tools/ImportLDIF.java
@@ -420,20 +420,8 @@
     }
 
     // Make sure that either the "includeBranchStrings" argument or the
-    // "backendID" argument was provided, but not both.
-    if(includeBranchStrings.isPresent())
-    {
-      if(backendID.isPresent())
-      {
-        int    msgID   = MSGID_LDIFIMPORT_CONFLICTING_OPTIONS;
-        String message = getMessage(msgID,
-                                    includeBranchStrings.getLongIdentifier(),
-                                    backendID.getLongIdentifier());
-        err.println(wrapText(message, MAX_LINE_WIDTH));
-        return 1;
-      }
-    }
-    else if(! backendID.isPresent())
+    // "backendID" argument was provided.
+    if(!includeBranchStrings.isPresent() && !backendID.isPresent())
     {
       int    msgID   = MSGID_LDIFIMPORT_MISSING_BACKEND_ARGUMENT;
       String message = getMessage(msgID,
@@ -925,12 +913,13 @@
       }
     }
 
-    // Make sure that if the "backendID" argument was provided and the "append"
-    // option was not provided, the "clearBackend" argument was also
-    // provided if there are more then one baseDNs for the backend being
-    // imported.
-    if(backendID.isPresent() && !append.isPresent() &&
-        defaultIncludeBranches.size() > 1 && !clearBackend.isPresent())
+    // Make sure that if the "backendID" argument was provided, no include base
+    // was included, and the "append" ption was not provided, the "clearBackend"
+    // argument was also provided if there are more then one baseDNs for the
+    // backend being imported.
+    if(backendID.isPresent() && !includeBranchStrings.isPresent() &&
+        !append.isPresent() && defaultIncludeBranches.size() > 1 &&
+        !clearBackend.isPresent())
     {
       StringBuilder builder = new StringBuilder();
       builder.append(backend.getBaseDNs()[0].toNormalizedString());
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java
index 3896ee9..2cb888e 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java
@@ -71,6 +71,11 @@
       "objectclass: organizationalUnit\n" +
       "ou: People\n" +
       "\n" +
+      "dn: ou=Others,ou=People,dc=importtest,dc=com\n" +
+      "objectclass: top\n" +
+      "objectclass: organizationalUnit\n" +
+      "ou: Others\n" +
+      "\n" +
       "dn: dc=importtest1,dc=com\n" +
       "objectclass: top\n" +
       "objectclass: domain\n" +
@@ -326,9 +331,10 @@
 
         if(baseDN.toString().equals("dc=importtest,dc=com"))
         {
-          assertEquals(entryContainer.getEntryCount(), 4);
+          assertEquals(entryContainer.getEntryCount(), 5);
           assertTrue(entryContainer.entryExists(baseDN));
           assertTrue(entryContainer.entryExists(DN.decode("ou=People,dc=importtest,dc=com")));
+          assertTrue(entryContainer.entryExists(DN.decode("ou=Others,ou=People,dc=importtest,dc=com")));
           assertTrue(entryContainer.entryExists(DN.decode("uid=user.0,ou=People,dc=importtest,dc=com")));
           assertTrue(entryContainer.entryExists(DN.decode("uid=user.539,ou=People,dc=importtest,dc=com")));
 
@@ -365,6 +371,94 @@
   }
 
   @Test(dependsOnMethods = "testImportAll")
+  public void testImportPartial() throws Exception
+  {
+    ArrayList<String> fileList = new ArrayList<String>();
+    fileList.add(homeDirName + File.separator + "top.ldif");
+    fileList.add(homeDirName + File.separator + "entries1.ldif");
+
+    ArrayList<DN> includeBranches = new ArrayList<DN>();
+    includeBranches.add(DN.decode("ou=People,dc=importtest,dc=com"));
+    ArrayList<DN> excludeBranches = new ArrayList<DN>();
+    excludeBranches.add(DN.decode("ou=Others,ou=People,dc=importtest,dc=com"));
+
+    ByteArrayOutputStream rejectedEntries = new ByteArrayOutputStream();
+    ByteArrayOutputStream skippedEntries = new ByteArrayOutputStream();
+    LDIFImportConfig importConfig = new LDIFImportConfig(fileList);
+    importConfig.setAppendToExistingData(false);
+    importConfig.setReplaceExistingEntries(false);
+    importConfig.setValidateSchema(true);
+    importConfig.writeRejectedEntries(rejectedEntries);
+    importConfig.writeSkippedEntries(skippedEntries);
+    importConfig.setIncludeBranches(includeBranches);
+    importConfig.setExcludeBranches(excludeBranches);
+
+    be=(BackendImpl) DirectoryServer.getBackend(beID);
+    TaskUtils.disableBackend(beID);
+    try
+    {
+      be.importLDIF(importConfig);
+    }
+    finally
+    {
+      TaskUtils.enableBackend(beID);
+    }
+
+    be=(BackendImpl) DirectoryServer.getBackend(beID);
+    RootContainer rootContainer = be.getRootContainer();
+    EntryContainer entryContainer;
+
+    assertTrue(rejectedEntries.size() <= 0);
+    for(DN baseDN : baseDNs)
+    {
+      entryContainer = rootContainer.getEntryContainer(baseDN);
+      entryContainer.sharedLock.lock();
+      try
+      {
+        assertNotNull(entryContainer);
+
+        if(baseDN.toString().equals("dc=importtest,dc=com"))
+        {
+          assertEquals(entryContainer.getEntryCount(), 5);
+          assertTrue(entryContainer.entryExists(baseDN));
+          assertTrue(entryContainer.entryExists(DN.decode("ou=People,dc=importtest,dc=com")));
+          assertTrue(entryContainer.entryExists(DN.decode("ou=Others,ou=People,dc=importtest,dc=com")));
+          assertTrue(entryContainer.entryExists(DN.decode("uid=user.0,ou=People,dc=importtest,dc=com")));
+          assertTrue(entryContainer.entryExists(DN.decode("uid=user.539,ou=People,dc=importtest,dc=com")));
+
+          VerifyConfig verifyConfig = new VerifyConfig();
+          verifyConfig.setBaseDN(baseDN);
+
+          Entry statEntry=bldStatEntry("");
+          be=(BackendImpl) DirectoryServer.getBackend(beID);
+          be.verifyBackend(verifyConfig, statEntry);
+          assertEquals(getStatEntryCount(statEntry, errorCount), 0);
+        }
+        else if(baseDN.toString().equals("dc=importtest1,dc=com"))
+        {
+          assertEquals(entryContainer.getEntryCount(), 3);
+          assertTrue(entryContainer.entryExists(baseDN));
+          assertTrue(entryContainer.entryExists(DN.decode("uid=user.446,dc=importtest1,dc=com")));
+          assertTrue(entryContainer.entryExists(DN.decode("uid=user.362,dc=importtest1,dc=com")));
+
+          VerifyConfig verifyConfig = new VerifyConfig();
+          verifyConfig.setBaseDN(baseDN);
+
+          Entry statEntry=bldStatEntry("");
+          be=(BackendImpl) DirectoryServer.getBackend(beID);
+          be.verifyBackend(verifyConfig, statEntry);
+          assertEquals(getStatEntryCount(statEntry, errorCount), 0);
+        }
+      }
+      finally
+      {
+        entryContainer.sharedLock.unlock();
+
+      }
+    }
+  }
+
+  @Test(dependsOnMethods = "testImportPartial")
   public void testImportReplaceExisting() throws Exception
   {
     ByteArrayOutputStream rejectedEntries = new ByteArrayOutputStream();
@@ -488,7 +582,7 @@
       {
         if(baseDN.toString().equals("dc=importtest,dc=com"))
         {
-          assertEquals(entryContainer.getEntryCount(), 4);
+          assertEquals(entryContainer.getEntryCount(), 5);
           assertTrue(entryContainer.entryExists(baseDN));
           assertTrue(entryContainer.entryExists(DN.decode("ou=People,dc=importtest,dc=com")));
           assertTrue(entryContainer.entryExists(DN.decode("uid=user.0,ou=People,dc=importtest,dc=com")));
@@ -510,7 +604,7 @@
     }
   }
 
-  @Test(dependsOnMethods = "testImportAll")
+  @Test(dependsOnMethods = "testImportPartial")
   public void testImportNotReplaceExisting() throws Exception
   {
     ByteArrayOutputStream rejectedEntries = new ByteArrayOutputStream();
@@ -534,7 +628,7 @@
     assertTrue(rejectedEntries.toString().contains("uid=user.446,dc=importtest1,dc=com"));
   }
 
-  @Test(dependsOnMethods = "testImportAll")
+  @Test(dependsOnMethods = "testImportPartial")
   public void testImportSkip() throws Exception
   {
     ArrayList<DN> excludeBranches = new ArrayList<DN>();
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestImportAndExport.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestImportAndExport.java
index 217b565..ccca0f0 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestImportAndExport.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestImportAndExport.java
@@ -32,10 +32,13 @@
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.DataProvider;
 import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.AddOperation;
 import org.opends.server.TestCaseUtils;
+import org.opends.server.protocols.internal.InternalClientConnection;
 import org.opends.server.api.TestTaskListener;
 import org.opends.server.types.Entry;
 import org.opends.server.types.ObjectClass;
+import org.opends.server.types.ResultCode;
 import org.opends.server.backends.task.TaskState;
 
 import static org.testng.Assert.*;
@@ -136,7 +139,7 @@
   public Object[][] createData() throws Exception
   {
     return new Object[][] {
-         // A fairly simple, valid import task.
+         // A fairly simple, valid import task using backend ID.
          {
               TestCaseUtils.makeEntry(
                    "dn: ds-task-id=" + UUID.randomUUID() +
@@ -155,6 +158,25 @@
               ),
               TaskState.COMPLETED_SUCCESSFULLY
          },
+         // A fairly simple, valid import task using include base DN.
+         {
+              TestCaseUtils.makeEntry(
+                   "dn: ds-task-id=" + UUID.randomUUID() +
+                        ",cn=Scheduled Tasks,cn=Tasks",
+                   "objectclass: top",
+                   "objectclass: ds-task",
+                   "objectclass: ds-task-import",
+                   "ds-task-class-name: org.opends.server.tasks.ImportTask",
+                   "ds-task-import-include-branch: dc=example,dc=com",
+                   "ds-task-import-ldif-file: " + ldifFile.getPath(),
+                   "ds-task-import-reject-file: " + rejectFile.getPath(),
+                   "ds-task-import-overwrite-rejects: TRUE",
+                   "ds-task-import-exclude-attribute: description",
+                   "ds-task-import-exclude-filter: (st=CA)",
+                   "ds-task-import-exclude-branch: o=exclude,dc=example,dc=com"
+              ),
+              TaskState.COMPLETED_SUCCESSFULLY
+         },
          // A complex, valid import task.
          {
               TestCaseUtils.makeEntry(
@@ -182,7 +204,7 @@
               ),
               TaskState.COMPLETED_SUCCESSFULLY
          },
-         // LDIF file does not exist.
+         // A partial, valid import task.
          {
               TestCaseUtils.makeEntry(
                    "dn: ds-task-id=" + UUID.randomUUID() +
@@ -191,40 +213,15 @@
                    "objectclass: ds-task",
                    "objectclass: ds-task-import",
                    "ds-task-class-name: org.opends.server.tasks.ImportTask",
-                   "ds-task-import-ldif-file: doesnotexist",
-                   "ds-task-import-backend-id: userRoot"
-              ),
-              TaskState.STOPPED_BY_ERROR
-         },
-         // Invalid exclude filter.
-         {
-              TestCaseUtils.makeEntry(
-                   "dn: ds-task-id=" + UUID.randomUUID() +
-                        ",cn=Scheduled Tasks,cn=Tasks",
-                   "objectclass: top",
-                   "objectclass: ds-task",
-                   "objectclass: ds-task-import",
-                   "ds-task-class-name: org.opends.server.tasks.ImportTask",
+                   "ds-task-import-include-branch: ou=people,dc=example,dc=com",
                    "ds-task-import-ldif-file: " + ldifFile.getPath(),
-                   "ds-task-import-backend-id: userRoot",
-                   "ds-task-import-exclude-filter: ()"
+                   "ds-task-import-reject-file: " + rejectFile.getPath(),
+                   "ds-task-import-overwrite-rejects: TRUE",
+                   "ds-task-import-exclude-attribute: description",
+                   "ds-task-import-exclude-filter: (st=CA)",
+                   "ds-task-import-exclude-branch: o=exclude,dc=example,dc=com"
               ),
-              TaskState.STOPPED_BY_ERROR
-         },
-         // Invalid include filter.
-         {
-              TestCaseUtils.makeEntry(
-                   "dn: ds-task-id=" + UUID.randomUUID() +
-                        ",cn=Scheduled Tasks,cn=Tasks",
-                   "objectclass: top",
-                   "objectclass: ds-task",
-                   "objectclass: ds-task-import",
-                   "ds-task-class-name: org.opends.server.tasks.ImportTask",
-                   "ds-task-import-ldif-file: " + ldifFile.getPath(),
-                   "ds-task-import-backend-id: userRoot",
-                   "ds-task-import-include-filter: ()"
-              ),
-              TaskState.STOPPED_BY_ERROR
+              TaskState.COMPLETED_SUCCESSFULLY
          },
          // Backend id does not exist.
          {
@@ -235,37 +232,8 @@
                    "objectclass: ds-task",
                    "objectclass: ds-task-import",
                    "ds-task-class-name: org.opends.server.tasks.ImportTask",
-                   "ds-task-import-ldif-file: " + ldifFile.getPath(),
-                   "ds-task-import-backend-id: doesnotexist"
-              ),
-              TaskState.STOPPED_BY_ERROR
-         },
-         // Backend does not support import.
-         {
-              TestCaseUtils.makeEntry(
-                   "dn: ds-task-id=" + UUID.randomUUID() +
-                        ",cn=Scheduled Tasks,cn=Tasks",
-                   "objectclass: top",
-                   "objectclass: ds-task",
-                   "objectclass: ds-task-import",
-                   "ds-task-class-name: org.opends.server.tasks.ImportTask",
-                   "ds-task-import-ldif-file: " + ldifFile.getPath(),
-                   "ds-task-import-backend-id: monitor"
-              ),
-              TaskState.STOPPED_BY_ERROR
-         },
-         // Backend does not handle include branch.
-         {
-              TestCaseUtils.makeEntry(
-                   "dn: ds-task-id=" + UUID.randomUUID() +
-                        ",cn=Scheduled Tasks,cn=Tasks",
-                   "objectclass: top",
-                   "objectclass: ds-task",
-                   "objectclass: ds-task-import",
-                   "ds-task-class-name: org.opends.server.tasks.ImportTask",
-                   "ds-task-import-ldif-file: " + ldifFile.getPath(),
-                   "ds-task-import-backend-id: userRoot",
-                   "ds-task-import-include-branch: dc=opends,dc=org"
+                   "ds-task-import-ldif-file: doesnotexist",
+                   "ds-task-import-backend-id: userRoot"
               ),
               TaskState.STOPPED_BY_ERROR
          },
@@ -289,12 +257,111 @@
   }
 
   /**
+   * Import and export tasks bad test data provider.
+   *
+   * @return The array of tasks test data.  The first column is a task entry
+   *  and the second column is the expected completed task state.
+   */
+  @DataProvider(name = "badimportexport")
+  public Object[][] createBadData() throws Exception
+  {
+    return new Object[][] {
+        // Invalid exclude filter.
+        {
+            TestCaseUtils.makeEntry(
+                "dn: ds-task-id=" + UUID.randomUUID() +
+                    ",cn=Scheduled Tasks,cn=Tasks",
+                "objectclass: top",
+                "objectclass: ds-task",
+                "objectclass: ds-task-import",
+                "ds-task-class-name: org.opends.server.tasks.ImportTask",
+                "ds-task-import-ldif-file: " + ldifFile.getPath(),
+                "ds-task-import-backend-id: userRoot",
+                "ds-task-import-exclude-filter: ()"
+            ),
+            ResultCode.UNWILLING_TO_PERFORM
+        },
+        // Invalid include filter.
+        {
+            TestCaseUtils.makeEntry(
+                "dn: ds-task-id=" + UUID.randomUUID() +
+                    ",cn=Scheduled Tasks,cn=Tasks",
+                "objectclass: top",
+                "objectclass: ds-task",
+                "objectclass: ds-task-import",
+                "ds-task-class-name: org.opends.server.tasks.ImportTask",
+                "ds-task-import-ldif-file: " + ldifFile.getPath(),
+                "ds-task-import-backend-id: userRoot",
+                "ds-task-import-include-filter: ()"
+            ),
+            ResultCode.UNWILLING_TO_PERFORM
+        },
+        // Backend id does not exist.
+        {
+            TestCaseUtils.makeEntry(
+                "dn: ds-task-id=" + UUID.randomUUID() +
+                    ",cn=Scheduled Tasks,cn=Tasks",
+                "objectclass: top",
+                "objectclass: ds-task",
+                "objectclass: ds-task-import",
+                "ds-task-class-name: org.opends.server.tasks.ImportTask",
+                "ds-task-import-ldif-file: " + ldifFile.getPath(),
+                "ds-task-import-backend-id: doesnotexist"
+            ),
+            ResultCode.UNWILLING_TO_PERFORM
+        },
+        // Backend does not support import.
+        {
+            TestCaseUtils.makeEntry(
+                "dn: ds-task-id=" + UUID.randomUUID() +
+                    ",cn=Scheduled Tasks,cn=Tasks",
+                "objectclass: top",
+                "objectclass: ds-task",
+                "objectclass: ds-task-import",
+                "ds-task-class-name: org.opends.server.tasks.ImportTask",
+                "ds-task-import-ldif-file: " + ldifFile.getPath(),
+                "ds-task-import-backend-id: monitor"
+            ),
+            ResultCode.UNWILLING_TO_PERFORM
+        },
+        // Backend does not handle include branch.
+        {
+            TestCaseUtils.makeEntry(
+                "dn: ds-task-id=" + UUID.randomUUID() +
+                    ",cn=Scheduled Tasks,cn=Tasks",
+                "objectclass: top",
+                "objectclass: ds-task",
+                "objectclass: ds-task-import",
+                "ds-task-class-name: org.opends.server.tasks.ImportTask",
+                "ds-task-import-ldif-file: " + ldifFile.getPath(),
+                "ds-task-import-backend-id: userRoot",
+                "ds-task-import-include-branch: dc=opends,dc=org"
+            ),
+            ResultCode.UNWILLING_TO_PERFORM
+        },
+        // Not specifying a destination.
+        {
+            TestCaseUtils.makeEntry(
+                "dn: ds-task-id=" + UUID.randomUUID() +
+                    ",cn=Scheduled Tasks,cn=Tasks",
+                "objectclass: top",
+                "objectclass: ds-task",
+                "objectclass: ds-task-import",
+                "ds-task-class-name: org.opends.server.tasks.ImportTask",
+                "ds-task-import-ldif-file: " + ldifFile.getPath()
+            ),
+            ResultCode.UNWILLING_TO_PERFORM
+        }
+    };
+  }
+
+  /**
    * Test that various import and export task definitions complete with the
    * expected state.
    * @param taskEntry The task entry.
    * @param expectedState The expected completion state of the task.
    */
-  @Test(enabled = false, dataProvider = "importexport", groups = "slow")
+  @Test(dataProvider = "importexport", groups = "slow")
   public void testImportExport(Entry taskEntry, TaskState expectedState)
        throws Exception
   {
@@ -329,4 +396,26 @@
     }
  }
 
+  /**
+   * Add a task definition and check that it completes with the expected state.
+   * @param taskEntry The task entry.
+   * @param resultCode The expected result code of the task add.
+   * @throws Exception If the test fails.
+   */
+  @Test(dataProvider = "badimportexport")
+  public void testBadTask(Entry taskEntry, ResultCode resultCode)
+      throws Exception
+  {
+    InternalClientConnection connection =
+        InternalClientConnection.getRootConnection();
+
+    // Add the task.
+    AddOperation addOperation =
+        connection.processAdd(taskEntry.getDN(),
+                              taskEntry.getObjectClasses(),
+                              taskEntry.getUserAttributes(),
+                              taskEntry.getOperationalAttributes());
+    assertEquals(addOperation.getResultCode(), resultCode);
+  }
+
 }
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/ImportLDIFTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/ImportLDIFTestCase.java
index 1fb1988..99e9ec8 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/ImportLDIFTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/ImportLDIFTestCase.java
@@ -51,6 +51,7 @@
   String configFilePath ;
   private String homeDirName;
   private String beID;
+  private String baseDN = "dc=example,dc=com";
 
   /**
   * Ensures that the ldif file is created with the entry.
@@ -196,6 +197,41 @@
     assertEntry(attr,true);
   }
 
+  /**
+   * Tests a simple Import LDIF using base DN with none of the attributes
+   * excluded or included. It is expected to import the entry(ies)
+   * with all the attributes in the ldif file.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test
+  public void testImportDefaultBaseDN() throws Exception
+  {
+
+    File reject = File.createTempFile("reject", ".ldif");
+    String rejectFilePath = reject.getAbsolutePath();
+    String[] args =
+    {
+      "-f", DirectoryServer.getConfigFile(),
+      "-l", ldifFilePath,
+      "-b", baseDN,
+      "-R", rejectFilePath
+    };
+    assertEquals(ImportLDIF.mainImportLDIF(args,false,System.out,System.err),0);
+    //Reject file should be empty.
+    assertRejectedFile(reject,true);
+    //check the presence of some random attributes.
+    Attribute[]  attr =
+    {
+      new Attribute ("description",
+          "This is the description for Aaccf Amar"),
+      new Attribute("mail","user.0@example.com"),
+      new Attribute ("creatorsname", "cn=Import") ,
+      new Attribute("modifiersname","cn=Import")
+    }    ;
+    assertEntry(attr,true);
+  }
+
 
 
   /**

--
Gitblit v1.10.0