| opendj-sdk/opends/src/server/org/opends/server/backends/jeb/ImportJob.java | ●●●●● patch | view | raw | blame | history | |
| opendj-sdk/opends/src/server/org/opends/server/tasks/ImportTask.java | ●●●●● patch | view | raw | blame | history | |
| opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/LdifFileWriter.java | ●●●●● patch | view | raw | blame | history | |
| opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TasksTestCase.java | ●●●●● patch | view | raw | blame | history | |
| opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestImportAndExport.java | ●●●●● patch | view | raw | blame | history |
opendj-sdk/opends/src/server/org/opends/server/backends/jeb/ImportJob.java
@@ -348,7 +348,6 @@ { ic.getEntryContainer().close(); } } // Sync the environment to disk. msgID = MSGID_JEB_IMPORT_CLOSING_DATABASE; @@ -356,6 +355,7 @@ logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.NOTICE, message, msgID); env.close(); } long finishTime = System.currentTimeMillis(); long importTime = (finishTime - startTime); opendj-sdk/opends/src/server/org/opends/server/tasks/ImportTask.java
@@ -252,15 +252,6 @@ message, msgID); return TaskState.STOPPED_BY_ERROR; } catch (Exception e) { int msgID = MSGID_LDIFIMPORT_CANNOT_PARSE_EXCLUDE_FILTER; String message = getMessage(msgID, filterString, stackTraceToSingleLineString(e)); logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR, message, msgID); return TaskState.STOPPED_BY_ERROR; } } ArrayList<SearchFilter> includeFilters = @@ -280,15 +271,6 @@ message, msgID); return TaskState.STOPPED_BY_ERROR; } catch (Exception e) { int msgID = MSGID_LDIFIMPORT_CANNOT_PARSE_INCLUDE_FILTER; String message = getMessage(msgID, filterString, stackTraceToSingleLineString(e)); logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR, message, msgID); return TaskState.STOPPED_BY_ERROR; } } @@ -354,7 +336,7 @@ for (String s : excludeBranchStrings) { DN excludeBranch = null; DN excludeBranch; try { excludeBranch = DN.decode(s); @@ -393,7 +375,7 @@ includeBranches = new ArrayList<DN>(includeBranchStrings.size()); for (String s : includeBranchStrings) { DN includeBranch = null; DN includeBranch; try { includeBranch = DN.decode(s); opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/LdifFileWriter.java
New file @@ -0,0 +1,158 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 * * * Portions Copyright 2006 Sun Microsystems, Inc. */ package org.opends.server.tasks; import org.opends.server.tools.makeldif.EntryWriter; import org.opends.server.tools.makeldif.MakeLDIFException; import org.opends.server.tools.makeldif.TemplateFile; import org.opends.server.types.Entry; import org.opends.server.types.LDIFExportConfig; import org.opends.server.types.ExistingFileBehavior; import org.opends.server.util.LDIFWriter; import org.opends.server.util.LDIFException; import org.opends.server.core.InitializationException; import java.io.IOException; import java.util.Random; import java.util.ArrayList; /** * This class makes test LDIF files using the makeldif package. */ public class LdifFileWriter implements EntryWriter { /** * The LDIF writer used to write the entries to the file. */ private LDIFWriter ldifWriter; /** * Construct an LdifFileWriter from an LDIF Writer. * @param ldifWriter The LDIF writer that should be used to write the entries. */ private LdifFileWriter(LDIFWriter ldifWriter) { this.ldifWriter = ldifWriter; } /** * Make an LDIF file containing test data. It uses a fixed value for the * random seed. * @param ldifPath The path to the LDIF file to be written. * @param resourcePath The path to the makeldif resource directory. * @param templatePath The path to the makeldif template file. * @throws IOException If there is an exception parsing the template or * generating the LDIF. * @throws InitializationException If there is an exception parsing the * template. * @throws MakeLDIFException If there is an exception parsing the template or * generating the LDIF. */ public static void makeLdif(String ldifPath, String resourcePath, String templatePath) throws IOException, InitializationException, MakeLDIFException { TemplateFile template = new TemplateFile(resourcePath, new Random(1)); ArrayList<String> warnings = new ArrayList<String>(); template.parse(templatePath, warnings); makeLdif(ldifPath, template); } /** * Make an LDIF file containing test data. It uses a fixed value for the * random seed. * @param ldifPath The path to the LDIF file to be written. * @param resourcePath The path to the makeldif resource directory. * @param templateLines The lines making up the template. * @throws IOException If there is an exception parsing the template or * generating the LDIF. * @throws InitializationException If there is an exception parsing the * template. * @throws MakeLDIFException If there is an exception parsing the template or * generating the LDIF. */ public static void makeLdif(String ldifPath, String resourcePath, String[] templateLines) throws IOException, InitializationException, MakeLDIFException { TemplateFile template = new TemplateFile(resourcePath, new Random(1)); ArrayList<String> warnings = new ArrayList<String>(); template.parse(templateLines, warnings); makeLdif(ldifPath, template); } /** * Make an LDIF file containing test data. * @param ldifPath The path to the LDIF file to be written. * @param template The makeldif template. * @throws IOException If there is an exception parsing the template or * generating the LDIF. * @throws MakeLDIFException If there is an exception parsing the template or * generating the LDIF. */ public static void makeLdif(String ldifPath, TemplateFile template) throws IOException, MakeLDIFException { LDIFExportConfig exportConfig = new LDIFExportConfig(ldifPath, ExistingFileBehavior.OVERWRITE); LDIFWriter ldifWriter = new LDIFWriter(exportConfig); template.generateLDIF(new LdifFileWriter(ldifWriter)); } /** * {@inheritDoc} */ public boolean writeEntry(Entry entry) throws IOException, MakeLDIFException { try { return ldifWriter.writeEntry(entry); } catch (LDIFException e) { e.printStackTrace(); return false; } } /** * {@inheritDoc} */ public void closeEntryWriter() { try { ldifWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TasksTestCase.java
@@ -30,7 +30,7 @@ import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.fail; import org.opends.server.DirectoryServerTestCase; import org.opends.server.schema.DirectoryStringSyntax; import static org.opends.server.config.ConfigConstants. @@ -54,6 +54,8 @@ /** * Add a task definition and check that it completes with the expected state. * The task is expected to complete quickly and the timeout is set * accordingly. * @param taskEntry The task entry. * @param expectedState The expected completion state of the task. * @throws Exception If the test fails. @@ -61,6 +63,19 @@ protected void testTask(Entry taskEntry, TaskState expectedState) throws Exception { testTask(taskEntry, expectedState, 10); } /** * Add a task definition and check that it completes with the expected state. * @param taskEntry The task entry. * @param expectedState The expected completion state of the task. * @param timeout The number of seconds to wait for the task to complete. * @throws Exception If the test fails. */ protected void testTask(Entry taskEntry, TaskState expectedState, int timeout) throws Exception { InternalClientConnection connection = InternalClientConnection.getRootConnection(); @@ -78,27 +93,42 @@ ATTR_TASK_COMPLETION_TIME.toLowerCase()); SearchFilter filter = SearchFilter.createFilterFromString("(objectclass=*)"); Entry resultEntry; String completionTime; int countdown = 10; // Do not wait forever. Entry resultEntry = null; String completionTime = null; long startMillisecs = System.currentTimeMillis(); do { countdown--; Thread.sleep(1000); InternalSearchOperation searchOperation = connection.processSearch(taskEntry.getDN(), SearchScope.BASE_OBJECT, filter); try { resultEntry = searchOperation.getSearchEntries().getFirst(); } catch (Exception e) { // FIXME How is this possible? // fail("Task entry was not returned from the search."); continue; } completionTime = resultEntry.getAttributeValue(completionTimeType, DirectoryStringSyntax.DECODER); } while (completionTime == null && countdown > 0); if (completionTime == null) { if (System.currentTimeMillis() - startMillisecs > 1000*timeout) { break; } Thread.sleep(10); } } while (completionTime == null); assertNotNull(completionTime, "The task did not complete"); if (completionTime == null) { fail("The task had not completed after " + timeout + " seconds."); } // Check that the task state is as expected. AttributeType taskStateType = opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/TestImportAndExport.java
New file @@ -0,0 +1,297 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 * * * Portions Copyright 2006 Sun Microsystems, Inc. */ package org.opends.server.tasks; import org.testng.annotations.Test; import org.testng.annotations.BeforeClass; import org.testng.annotations.AfterClass; import org.testng.annotations.DataProvider; import org.opends.server.core.DirectoryServer; import org.opends.server.TestCaseUtils; import org.opends.server.types.Entry; import org.opends.server.backends.task.TaskState; import java.io.File; import java.util.UUID; /** * Tests invocation of the backup and restore tasks, but does not aim to * thoroughly test the underlying backend implementations. */ public class TestImportAndExport extends TasksTestCase { /** * A makeldif template used to create some test entries. */ private static String[] template = new String[] { "define suffix=dc=example,dc=com", "define maildomain=example.com", "define numusers=101", "", "branch: [suffix]", "", "branch: ou=People,[suffix]", "subordinateTemplate: person:[numusers]", "", "template: person", "rdnAttr: uid", "objectClass: top", "objectClass: person", "objectClass: organizationalPerson", "objectClass: inetOrgPerson", "givenName: <first>", "sn: <last>", "cn: {givenName} {sn}", "initials: {givenName:1}<random:chars:" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ:1>{sn:1}", "employeeNumber: <sequential:0>", "uid: user.{employeeNumber}", "mail: {uid}@[maildomain]", "userPassword: password", "telephoneNumber: <random:telephone>", "homePhone: <random:telephone>", "pager: <random:telephone>", "mobile: <random:telephone>", "street: <random:numeric:5> <file:streets> Street", "l: <file:cities>", "st: <file:states>", "postalCode: <random:numeric:5>", "postalAddress: {cn}${street}${l}, {st} {postalCode}", "description: This is the description for {cn}.", ""}; /** * A temporary LDIF file containing some test entries. */ private File ldifFile; /** * A temporary file to contain rejected entries. */ private File rejectFile; @BeforeClass public void setUp() throws Exception { // The server must be running for these tests. TestCaseUtils.startServer(); // Create a temporary test LDIF file. ldifFile = File.createTempFile("import-test", ".ldif"); String resourcePath = DirectoryServer.getServerRoot() + File.separator + "config" + File.separator + "MakeLDIF"; LdifFileWriter.makeLdif(ldifFile.getPath(), resourcePath, template); // Create a temporary rejects file. rejectFile = File.createTempFile("import-test-rejects", ".ldif"); } @AfterClass public void tearDown() { ldifFile.delete(); rejectFile.delete(); } /** * Import and export tasks 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 = "importexport") public Object[][] createData() throws Exception { return new Object[][] { // A fairly simple valid import task. { 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-backend-id: userRoot", "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( "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-backend-id: userRoot", "ds-task-import-ldif-file: " + ldifFile.getPath(), "ds-task-import-is-compressed: FALSE", "ds-task-import-is-encrypted: FALSE", "ds-task-import-reject-file: " + rejectFile.getPath(), "ds-task-import-overwrite-rejects: FALSE", "ds-task-import-append: TRUE", "ds-task-import-replace-existing: TRUE", "ds-task-import-skip-schema-validation: TRUE", "ds-task-import-include-branch: dc=example,dc=com", "ds-task-import-exclude-branch: o=exclude,dc=example,dc=com", "ds-task-import-include-attribute: cn", "ds-task-import-include-attribute: sn", "ds-task-import-include-attribute: uid", "ds-task-import-include-filter: (objectclass=*)" ), TaskState.COMPLETED_SUCCESSFULLY }, // LDIF file 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: 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-ldif-file: " + ldifFile.getPath(), "ds-task-import-backend-id: userRoot", "ds-task-import-exclude-filter: ()" ), 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 }, // 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" ), 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" ), TaskState.STOPPED_BY_ERROR }, // Rejects file is a directory. { 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-backend-id: userRoot", "ds-task-import-ldif-file: " + ldifFile.getPath(), "ds-task-import-reject-file: " + ldifFile.getParent(), "ds-task-import-overwrite-rejects: TRUE" ), TaskState.STOPPED_BY_ERROR }, }; } /** * 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(dataProvider = "importexport", groups = "slow") public void testImportExport(Entry taskEntry, TaskState expectedState) throws Exception { testTask(taskEntry, expectedState); } }