mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jarnou
09.13.2007 9a8d97c273430b8eb0ab9afc4209f555321da4e8
Bug: 1428
Synopsis: import-ldif could allow to write skipped entries to a specified file

Proposed solution
-------------------------------
I've added an option to the import tool so that the skipped entries (the entries that do not match criteria) are logged in a given file if required.
Additionally the option -O, --overwriteRejects has been renamed into:
-O, --overwrite. This option is now common to both reject file and skip file.
Indeed if a user wants to append or overwrite a reject file, it is likely that he wants the same for the skip file.

The new option is -K (--skipFile), the updated option is -O (--overwrite)

The usage:

This utility may be used to import LDIF data into a Directory Server backend
Usage: java org.opends.server.tools.ImportLDIF {options}
where {options} include:
-V, --version
Display Directory Server version information
...
-R, --rejectFile {rejectFile}
Write rejected entries to the specified file
-K, --skipFile {skipFile}
Write skipped entries to the specified file
-O, --overwrite
Overwrite an existing rejects and/or skip file rather than appending to it
...
8 files modified
424 ■■■■■ changed files
opends/src/server/org/opends/server/config/ConfigConstants.java 15 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ToolMessages.java 29 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/UtilityMessages.java 32 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tasks/ImportTask.java 46 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/ImportLDIF.java 47 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/LDIFImportConfig.java 124 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/LDIFReader.java 65 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java 66 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/config/ConfigConstants.java
@@ -3749,17 +3749,24 @@
       NAME_PREFIX_TASK + "import-reject-file";
  /**
   * The name of the attribute in an import task definition that specifies
   * the path to a file into which skipped entries may be written if they
   * do not match criteria during the import process.
   */
  public static final String ATTR_IMPORT_SKIP_FILE =
       NAME_PREFIX_TASK + "import-skip-file";
  /**
   * The name of the attribute in an import task definition that specifies
   * whether to overwrite an existing rejects file when performing an LDIF
   * import rather than appending to it.
   * whether to overwrite an existing rejects and/or skip file when performing
   * an LDIF import rather than appending to it.
   */
  public static final String ATTR_IMPORT_OVERWRITE_REJECTS =
  public static final String ATTR_IMPORT_OVERWRITE =
       NAME_PREFIX_TASK + "import-overwrite-rejects";
  /**
   * The name of the attribute in an import task definition that specifies
   * whether to skip schema validation during the import.
opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -687,7 +687,7 @@
   * The message ID for the message that will be used as the description of the
   * overwriteRejects argument.  This does not take any arguments.
   */
  public static final int MSGID_LDIFIMPORT_DESCRIPTION_OVERWRITE_REJECTS =
  public static final int MSGID_LDIFIMPORT_DESCRIPTION_OVERWRITE =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 79;
@@ -8999,6 +8999,22 @@
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1196;
  /**
   * The message ID for the message that will be used as the description of the
   * skipFile argument.  This does not take any arguments.
   */
  public static final int MSGID_LDIFIMPORT_DESCRIPTION_SKIP_FILE =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1197;
  /**
   * The message ID for the message that will be used if an error occurs while
   * trying to open the skip file.  This takes two arguments, which are the
   * path to the skip file and a string representation of the exception that
   * was caught.
   */
  public static final int MSGID_LDIFIMPORT_CANNOT_OPEN_SKIP_FILE =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1198;
  /**
   * Associates a set of generic messages with the message IDs defined in this
@@ -9245,9 +9261,14 @@
                    "import");
    registerMessage(MSGID_LDIFIMPORT_DESCRIPTION_REJECT_FILE,
                    "Write rejected entries to the specified file");
    registerMessage(MSGID_LDIFIMPORT_DESCRIPTION_OVERWRITE_REJECTS,
                    "Overwrite an existing rejects file rather than " +
                    "appending to it");
    registerMessage(MSGID_LDIFIMPORT_DESCRIPTION_SKIP_FILE,
                    "Write skipped entries to the specified file");
    registerMessage(MSGID_LDIFIMPORT_CANNOT_OPEN_SKIP_FILE,
                    "An error occurred while trying to open the skip " +
                    "file %s for writing:  %s");
    registerMessage(MSGID_LDIFIMPORT_DESCRIPTION_OVERWRITE,
                    "Overwrite an existing rejects and/or skip file " +
                    "rather than appending to it");
    registerMessage(MSGID_LDIFIMPORT_DESCRIPTION_RANDOM_SEED,
                    "Seed for the MakeLDIF random number generator");
    registerMessage(MSGID_LDIFIMPORT_DESCRIPTION_SKIP_SCHEMA_VALIDATION,
opends/src/server/org/opends/server/messages/UtilityMessages.java
@@ -1667,8 +1667,6 @@
  public static final int MSGID_RENAMEFILE_CANNOT_DELETE_TARGET =
       CATEGORY_MASK_UTIL | SEVERITY_MASK_SEVERE_ERROR | 158;
  /**
   * The message ID for the message that will be used if a client certificate is
   * rejected because it is expired.  This takes two arguments, which are the
@@ -1727,6 +1725,28 @@
  /**
   * The message ID for the message that will be used if an attempt is made to
   * write a skip file but the specified file already exists.  This takes a
   * single argument, which is the name of the file.
   */
  public static final int MSGID_SKIP_FILE_EXISTS =
       CATEGORY_MASK_UTIL | SEVERITY_MASK_SEVERE_ERROR | 164;
  /**
   * The message ID for the message that will be used if an attempt is made to
   * read an LDIF entry, but that entry does not match the criteria.
   * This takes three arguments, which are the DN of the entry,
   * the starting line number for the entry, and a message that explains why
   * it does not match the criteria.
   */
  public static final int MSGID_LDIF_SKIP =
       CATEGORY_MASK_UTIL | SEVERITY_MASK_MILD_ERROR | 165;
  /**
   * Associates a set of generic messages with the message IDs defined in this
   * class.
   */
@@ -1812,6 +1832,10 @@
                    "Entry %s read from LDIF starting at line %d is not " +
                    "valid because it violates the server's schema " +
                    "configuration:  %s");
    registerMessage(MSGID_LDIF_SKIP,
                    "Skipping entry %s because the DN is not one that " +
                    "should be included based on the include and " +
                    "exclude branches");
    registerMessage(MSGID_LDIF_FILE_EXISTS,
                    "The specified LDIF file %s already exists and the " +
                    "export configuration indicates that no attempt should " +
@@ -1829,6 +1853,10 @@
                    "The specified reject file %s already exists and the " +
                    "import configuration indicates that no attempt should " +
                    "be made to append to or replace the file");
    registerMessage(MSGID_SKIP_FILE_EXISTS,
                    "The specified skip file %s already exists and the " +
                    "import configuration indicates that no attempt should " +
                    "be made to append to or replace the file");
    registerMessage(MSGID_LDIF_COULD_NOT_EVALUATE_FILTERS_FOR_IMPORT,
                    "An error occurred while attempting to determine whether " +
                    "LDIF entry \"%s\" starting at line %d should be " +
opends/src/server/org/opends/server/tasks/ImportTask.java
@@ -77,11 +77,12 @@
  boolean append                  = false;
  boolean isCompressed            = false;
  boolean isEncrypted             = false;
  boolean overwriteRejects        = false;
  boolean overwrite               = false;
  boolean replaceExisting         = false;
  boolean skipSchemaValidation    = false;
  String  backendID               = null;
  String  rejectFile              = null;
  String  skipFile                = null;
  ArrayList<String>  excludeAttributeStrings = null;
  ArrayList<String>  excludeBranchStrings    = null;
  ArrayList<String>  excludeFilterStrings    = null;
@@ -126,7 +127,8 @@
    AttributeType typeIncludeFilter;
    AttributeType typeExcludeFilter;
    AttributeType typeRejectFile;
    AttributeType typeOverwriteRejects;
    AttributeType typeSkipFile;
    AttributeType typeOverwrite;
    AttributeType typeSkipSchemaValidation;
    AttributeType typeIsCompressed;
    AttributeType typeIsEncrypted;
@@ -153,8 +155,10 @@
         getAttributeType(ATTR_IMPORT_EXCLUDE_FILTER, true);
    typeRejectFile =
         getAttributeType(ATTR_IMPORT_REJECT_FILE, true);
    typeOverwriteRejects =
         getAttributeType(ATTR_IMPORT_OVERWRITE_REJECTS, true);
    typeSkipFile =
      getAttributeType(ATTR_IMPORT_SKIP_FILE, true);
    typeOverwrite =
         getAttributeType(ATTR_IMPORT_OVERWRITE, true);
    typeSkipSchemaValidation =
         getAttributeType(ATTR_IMPORT_SKIP_SCHEMA_VALIDATION, true);
    typeIsCompressed =
@@ -197,8 +201,11 @@
    attrList = taskEntry.getAttribute(typeRejectFile);
    rejectFile = TaskUtils.getSingleValueString(attrList);
    attrList = taskEntry.getAttribute(typeOverwriteRejects);
    overwriteRejects = TaskUtils.getBoolean(attrList, false);
    attrList = taskEntry.getAttribute(typeSkipFile);
    skipFile = TaskUtils.getSingleValueString(attrList);
    attrList = taskEntry.getAttribute(typeOverwrite);
    overwrite = TaskUtils.getBoolean(attrList, false);
    attrList = taskEntry.getAttribute(typeSkipSchemaValidation);
    skipSchemaValidation = TaskUtils.getBoolean(attrList, false);
@@ -444,7 +451,7 @@
      try
      {
        ExistingFileBehavior existingBehavior;
        if (overwriteRejects)
        if (overwrite)
        {
          existingBehavior = ExistingFileBehavior.OVERWRITE;
        }
@@ -465,6 +472,31 @@
      }
    }
    if (skipFile != null)
    {
      try
      {
        ExistingFileBehavior existingBehavior;
        if (overwrite)
        {
          existingBehavior = ExistingFileBehavior.OVERWRITE;
        }
        else
        {
          existingBehavior = ExistingFileBehavior.APPEND;
        }
        importConfig.writeRejectedEntries(skipFile, existingBehavior);
      }
      catch (Exception e)
      {
        int    msgID   = MSGID_LDIFIMPORT_CANNOT_OPEN_SKIP_FILE;
        String message = getMessage(msgID, skipFile, getExceptionMessage(e));
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        return TaskState.STOPPED_BY_ERROR;
      }
    }
    // Get the set of base DNs for the backend as an array.
    DN[] baseDNs = new DN[defaultIncludeBranches.size()];
opends/src/server/org/opends/server/tools/ImportLDIF.java
@@ -139,7 +139,7 @@
    BooleanArgument displayUsage            = null;
    BooleanArgument isCompressed            = null;
    BooleanArgument isEncrypted             = null;
    BooleanArgument overwriteRejects        = null;
    BooleanArgument overwrite               = null;
    BooleanArgument quietMode               = null;
    BooleanArgument replaceExisting         = null;
    BooleanArgument skipSchemaValidation    = null;
@@ -155,6 +155,7 @@
    StringArgument  includeFilterStrings    = null;
    StringArgument  ldifFiles               = null;
    StringArgument  rejectFile              = null;
    StringArgument  skipFile                = null;
    StringArgument  templateFile            = null;
@@ -270,10 +271,17 @@
      argParser.addArgument(rejectFile);
      overwriteRejects =
           new BooleanArgument("overwriterejects", 'O', "overwriteRejects",
                               MSGID_LDIFIMPORT_DESCRIPTION_OVERWRITE_REJECTS);
      argParser.addArgument(overwriteRejects);
      skipFile =
           new StringArgument("skipfile", 'K', "skipFile", false, false,
                              true, "{skipFile}", null, null,
                              MSGID_LDIFIMPORT_DESCRIPTION_SKIP_FILE);
      argParser.addArgument(skipFile);
      overwrite =
           new BooleanArgument("overwrite", 'O', "overwrite",
                               MSGID_LDIFIMPORT_DESCRIPTION_OVERWRITE);
      argParser.addArgument(overwrite);
      randomSeed =
@@ -971,7 +979,7 @@
      try
      {
        ExistingFileBehavior existingBehavior;
        if (overwriteRejects.isPresent())
        if (overwrite.isPresent())
        {
          existingBehavior = ExistingFileBehavior.OVERWRITE;
        }
@@ -994,6 +1002,33 @@
      }
    }
    if (skipFile != null)
    {
      try
      {
        ExistingFileBehavior existingBehavior;
        if (overwrite.isPresent())
        {
          existingBehavior = ExistingFileBehavior.OVERWRITE;
        }
        else
        {
          existingBehavior = ExistingFileBehavior.APPEND;
        }
        importConfig.writeSkippedEntries(skipFile.getValue(),
                                          existingBehavior);
      }
      catch (Exception e)
      {
        int    msgID   = MSGID_LDIFIMPORT_CANNOT_OPEN_SKIP_FILE;
        String message = getMessage(msgID, skipFile.getValue(),
                                    getExceptionMessage(e));
        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR,
                 message, msgID);
        return 1;
      }
    }
    // Get the set of base DNs for the backend as an array.
    DN[] baseDNs = new DN[defaultIncludeBranches.size()];
opends/src/server/org/opends/server/types/LDIFImportConfig.java
@@ -109,6 +109,9 @@
  // The buffered writer to which rejected entries should be written.
  private BufferedWriter rejectWriter;
  // The buffered writer to which rejected entries should be written.
  private BufferedWriter skipWriter;
  // The input stream to use to read the data to import.
  private InputStream ldifInputStream;
@@ -184,6 +187,7 @@
    validateSchema         = true;
    reader                 = null;
    rejectWriter           = null;
    skipWriter             = null;
    excludeAttributes      = new HashSet<AttributeType>();
    includeAttributes      = new HashSet<AttributeType>();
    includeAllUserAttrs    = false;
@@ -223,6 +227,7 @@
    validateSchema         = true;
    reader                 = null;
    rejectWriter           = null;
    skipWriter             = null;
    excludeAttributes      = new HashSet<AttributeType>();
    includeAttributes      = new HashSet<AttributeType>();
    includeAllUserAttrs    = false;
@@ -260,6 +265,7 @@
    isEncrypted            = false;
    reader                 = null;
    rejectWriter           = null;
    skipWriter             = null;
    excludeAttributes      = new HashSet<AttributeType>();
    includeAttributes      = new HashSet<AttributeType>();
    includeAllUserAttrs    = false;
@@ -295,6 +301,7 @@
    isEncrypted            = false;
    reader                 = getBufferedReader(ldifInputReader);
    rejectWriter           = null;
    skipWriter             = null;
    excludeAttributes      = new HashSet<AttributeType>();
    includeAttributes      = new HashSet<AttributeType>();
    includeAllUserAttrs    = false;
@@ -437,7 +444,17 @@
    return rejectWriter;
  }
  /**
   * Retrieves the writer that should be used to write entries that
   * are skipped because they don't match the criteri.
   *
   * @return  The skip writer, or <CODE>null</CODE> if none is to be
   *          used.
   */
  public BufferedWriter getSkipWriter()
  {
    return skipWriter;
  }
  /**
   * Indicates that rejected entries should be written to the
@@ -533,7 +550,97 @@
         new BufferedWriter(new OutputStreamWriter(outputStream));
  }
  /**
   * Indicates that skipped entries should be written to the
   * specified file.  Note that this applies only to entries that are
   * skipped because they matched exclude criteria.
   *
   * @param  skipFile              The path to the file to which
   *                               skipped information should be
   *                               written.
   * @param  existingFileBehavior  Indicates how to treat an existing
   *                               file.
   *
   * @throws  IOException  If a problem occurs while opening the
   *                       skip file for writing.
   */
  public void writeSkippedEntries(String skipFile,
                   ExistingFileBehavior existingFileBehavior)
         throws IOException
  {
    if (skipFile == null)
    {
      if (skipWriter != null)
      {
        try
        {
          skipWriter.close();
        } catch (Exception e) {}
        skipWriter = null;
      }
      return;
    }
    switch (existingFileBehavior)
    {
      case APPEND:
        skipWriter =
             new BufferedWriter(new FileWriter(skipFile, true));
        break;
      case OVERWRITE:
        skipWriter =
             new BufferedWriter(new FileWriter(skipFile, false));
        break;
      case FAIL:
        File f = new File(skipFile);
        if (f.exists())
        {
          throw new IOException(getMessage(MSGID_SKIP_FILE_EXISTS,
                                           skipFile));
        }
        else
        {
          skipWriter =
               new BufferedWriter(new FileWriter(skipFile));
        }
        break;
    }
  }
  /**
   * Indicates that skipped entries should be written to the provided
   * output stream.  Note that this does not apply to entries that are
   * rejected because they are invalid (e.g., are malformed or don't
   * conform to schema requirements), but only apply to entries that
   * are skipped because they matched exclude criteria.
   *
   * @param  outputStream  The output stream to which skipped entries
   *                       should be written.
   */
  public void writeSkippedEntries(OutputStream outputStream)
  {
    if (outputStream == null)
    {
      if (skipWriter != null)
      {
        try
        {
          skipWriter.close();
        } catch (Exception e) {}
        skipWriter = null;
      }
      return;
    }
    skipWriter =
         new BufferedWriter(new OutputStreamWriter(outputStream));
  }
  /**
   * Indicates whether to append to an existing data set or completely
@@ -1221,6 +1328,21 @@
        }
      }
    }
    if (skipWriter != null)
    {
      try
      {
        skipWriter.close();
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
      }
    }
  }
}
opends/src/server/org/opends/server/util/LDIFReader.java
@@ -224,6 +224,10 @@
                    entryDN);
        }
        entriesRead++;
        int    msgID   = MSGID_LDIF_SKIP;
        String message = getMessage(msgID, String.valueOf(entryDN),
            lastEntryLineNumber);
        logToSkipWriter(lines, message);
        entriesIgnored++;
        continue;
      }
@@ -269,6 +273,10 @@
                "that should be included based on the include and exclude " +
                "filters.", entryDN);
          }
          int    msgID   = MSGID_LDIF_SKIP;
          String message = getMessage(msgID, String.valueOf(entryDN),
              lastEntryLineNumber);
          logToSkipWriter(lines, message);
          entriesIgnored++;
          continue;
        }
@@ -294,6 +302,10 @@
             pluginConfigManager.invokeLDIFImportPlugins(importConfig, entry);
        if (! pluginResult.continueEntryProcessing())
        {
          int    msgID   = MSGID_LDIF_SKIP;
          String message = getMessage(msgID, String.valueOf(entryDN),
              lastEntryLineNumber);
          logToSkipWriter(lines, message);
          entriesIgnored++;
          continue;
        }
@@ -1738,8 +1750,6 @@
    return value;
  }
  /**
   * Log a message to the reject writer if one is configured.
   *
@@ -1754,18 +1764,56 @@
    BufferedWriter rejectWriter = importConfig.getRejectWriter();
    if (rejectWriter != null)
    {
      logToWriter(rejectWriter, lines, message);
    }
  }
  /**
   * Log a message to the reject writer if one is configured.
   *
   * @param lines
   *          The set of rejected lines.
   * @param message
   *          The associated error message.
   */
  private void logToSkipWriter(LinkedList<StringBuilder> lines,
      String message) {
    BufferedWriter skipWriter = importConfig.getSkipWriter();
    if (skipWriter != null)
    {
      logToWriter(skipWriter, lines, message);
    }
  }
  /**
   * Log a message to the given writer.
   *
   * @param writer
   *          The writer to write to.
   * @param lines
   *          The set of rejected lines.
   * @param message
   *          The associated error message.
   */
  private void logToWriter(BufferedWriter writer,
      LinkedList<StringBuilder> lines,
      String message)
  {
    if (writer != null)
    {
      try
      {
        rejectWriter.write("# ");
        rejectWriter.write(message);
        rejectWriter.newLine();
        writer.write("# ");
        writer.write(message);
        writer.newLine();
        for (StringBuilder sb : lines)
        {
          rejectWriter.write(sb.toString());
          rejectWriter.newLine();
          writer.write(sb.toString());
          writer.newLine();
        }
        rejectWriter.newLine();
        writer.newLine();
      }
      catch (Exception e)
      {
@@ -1776,5 +1824,6 @@
      }
    }
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java
@@ -197,6 +197,36 @@
      "postalAddress: Annalee Avard$43221 Hill Street$Charleston, CO  60918\n" +
      "description: This is the description for Annalee Bogard.\n";
  private String skippedEntries =
    "dn: dc=skipped,dc=importtest1,dc=com\n" +
    "objectclass: top\n" +
    "objectclass: domain\n" +
    "dc: skipped\n" +
    "\n" +
    "dn: uid=user.446,dc=skipped,dc=importtest1,dc=com\n" +
    "objectClass: top\n" +
    "objectClass: person\n" +
    "objectClass: organizationalPerson\n" +
    "objectClass: inetOrgPerson\n" +
    "givenName: Annalee\n" +
    "sn: Bogard\n" +
    "cn: Annalee Bogard\n" +
    "initials: ANG\n" +
    "employeeNumber: 446\n" +
    "uid: user.446\n" +
    "mail: user.446@example.com\n" +
    "userPassword: password\n" +
    "telephoneNumber: 875-335-8882\n" +
    "homePhone: 181-995-6635\n" +
    "pager: 586-905-4185\n" +
    "mobile: 826-857-7592\n" +
    "street: 43221 Hill Street\n" +
    "l: Charleston\n" +
    "st: CO\n" +
    "postalCode: 60918\n" +
    "postalAddress: Annalee Avard$43221 Hill Street$Charleston, CO  60918\n" +
    "description: This is the description for Annalee Bogard.\n";
  @BeforeClass
  public void setUp() throws Exception
@@ -231,6 +261,12 @@
    writer.close();
    ldifFile.close();
    ldifFile = new FileOutputStream(homeDirName + File.separator + "skipped.ldif");
    writer = new PrintStream(ldifFile);
    writer.println(skippedEntries);
    writer.close();
    ldifFile.close();
    baseDNs = new DN[]
    {
@@ -255,11 +291,13 @@
    fileList.add(homeDirName + File.separator + "entries1.ldif");
    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);
    be=(BackendImpl) DirectoryServer.getBackend(beID);
    TaskUtils.disableBackend(beID);
@@ -277,6 +315,7 @@
    EntryContainer entryContainer;
    assertTrue(rejectedEntries.size() <= 0);
    assertTrue(skippedEntries.size() <= 0);
    for(DN baseDN : baseDNs)
    {
      entryContainer = rootContainer.getEntryContainer(baseDN);
@@ -495,6 +534,33 @@
    assertTrue(rejectedEntries.toString().contains("uid=user.446,dc=importtest1,dc=com"));
  }
  @Test(dependsOnMethods = "testImportAll")
  public void testImportSkip() throws Exception
  {
    ArrayList<DN> excludeBranches = new ArrayList<DN>();
    excludeBranches.add(DN.decode("dc=skipped,dc=importtest1,dc=com"));
    ByteArrayOutputStream skippedEntries = new ByteArrayOutputStream();
    LDIFImportConfig importConfig = new LDIFImportConfig(homeDirName + File.separator + "skipped.ldif");
    importConfig.setAppendToExistingData(false);
    importConfig.setReplaceExistingEntries(true);
    importConfig.setValidateSchema(true);
    importConfig.setExcludeBranches(excludeBranches);
    importConfig.writeSkippedEntries(skippedEntries);
    be=(BackendImpl) DirectoryServer.getBackend(beID);
    TaskUtils.disableBackend(beID);
    try
    {
      be.importLDIF(importConfig);
    }
    finally
    {
      TaskUtils.enableBackend(beID);
    }
    assertTrue(skippedEntries.toString().contains("dc=skipped,dc=importtest1,dc=com"));
    assertTrue(skippedEntries.toString().contains("uid=user.446,dc=skipped,dc=importtest1,dc=com"));
  }
      /**
     * Builds an entry suitable for using in the verify job to gather statistics about
     * the verify.