From 76f8740cd3de4bd7b437d87e476faa22e8913fce Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 11 Feb 2014 18:52:11 +0000 Subject: [PATCH] Merged HEAD-BUG-FIX (4.3/Cloud) to HEAD (4.3/Cloud) 57041: Merged V4.2-BUG-FIX (4.2.1) to HEAD-BUG-FIX (Cloud/4.3) 56508: Merged HEAD-BUG-FIX to V4.2-BUG-FIX (4.2.1) 55931: <> Merged V4.1-BUG-FIX (4.1.7) to HEAD-BUG-FIX (4.2) 55872: Merged DEV to V4.1-BUG-FIX (4.1.7) 55854: MNT-9067: bulkimport "Replace existing files" option does not work when versioning is enabled Clear version history on import versioned file and replace existing versioned file. Remove versionable aspect on import non versioned file and replace existing versioned file. Added unit test. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@61675 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../bulkimport/impl/AbstractNodeImporter.java | 32 ++- .../impl/StreamingNodeImporterFactory.java | 2 +- .../repo/bulkimport/impl/BulkImportTest.java | 211 ++++++++++++++++++ .../bulkimport3/initial/fileWithVersions.txt | 1 + .../initial/fileWithVersions.txt.v1 | 1 + .../initial/fileWithVersions.txt.v2 | 1 + .../initial/fileWithVersions.txt.v3 | 1 + .../fileWithVersions.txt | 1 + .../fileWithVersions.txt | 1 + .../fileWithVersions.txt.v1 | 1 + .../fileWithVersions.txt.v2 | 1 + .../fileWithVersions.txt.v3 | 1 + .../fileWithVersions.txt.v4 | 1 + 13 files changed, 243 insertions(+), 12 deletions(-) create mode 100644 source/test-resources/bulkimport3/initial/fileWithVersions.txt create mode 100644 source/test-resources/bulkimport3/initial/fileWithVersions.txt.v1 create mode 100644 source/test-resources/bulkimport3/initial/fileWithVersions.txt.v2 create mode 100644 source/test-resources/bulkimport3/initial/fileWithVersions.txt.v3 create mode 100644 source/test-resources/bulkimport3/replace_with_non_versioned/fileWithVersions.txt create mode 100644 source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt create mode 100644 source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v1 create mode 100644 source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v2 create mode 100644 source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v3 create mode 100644 source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v4 diff --git a/source/java/org/alfresco/repo/bulkimport/impl/AbstractNodeImporter.java b/source/java/org/alfresco/repo/bulkimport/impl/AbstractNodeImporter.java index b6f7456d07..6c0d059f00 100644 --- a/source/java/org/alfresco/repo/bulkimport/impl/AbstractNodeImporter.java +++ b/source/java/org/alfresco/repo/bulkimport/impl/AbstractNodeImporter.java @@ -173,30 +173,28 @@ public abstract class AbstractNodeImporter implements NodeImporter return(result); } - protected final int importImportableItemFile(NodeRef nodeRef, ImportableItem importableItem, MetadataLoader.Metadata metadata) + protected final int importImportableItemFile(NodeRef nodeRef, ImportableItem importableItem, MetadataLoader.Metadata metadata, NodeState nodeState) { int result = 0; if (importableItem.hasVersionEntries()) { - // If cm:versionable isn't listed as one of the aspects for this node, add it - cm:versionable is required for nodes that have versions - if (!metadata.getAspects().contains(ContentModel.ASPECT_VERSIONABLE)) - { - if (logger.isWarnEnabled()) logger.warn("Metadata for file '" + getFileName(importableItem.getHeadRevision().getContentFile()) + "' was missing the cm:versionable aspect, yet it has " + importableItem.getVersionEntries().size() + " versions. Adding cm:versionable."); - metadata.addAspect(ContentModel.ASPECT_VERSIONABLE); - } - - result = importContentVersions(nodeRef, importableItem); + result = importContentVersions(nodeRef, importableItem, nodeState); } else { + if (nodeState == NodeState.REPLACED) + { + nodeService.removeAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE); + } + importContentAndMetadata(nodeRef, importableItem.getHeadRevision(), metadata); } return(result); } - protected final int importContentVersions(NodeRef nodeRef, ImportableItem importableItem) + protected final int importContentVersions(NodeRef nodeRef, ImportableItem importableItem, NodeState nodeState) { int result = 0; Map versionProperties = new HashMap(); @@ -206,6 +204,11 @@ public abstract class AbstractNodeImporter implements NodeImporter //versionProperties.put(ContentModel.PROP_VERSION_LABEL.toPrefixString(), String.valueOf(versionEntry.getVersion())); versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR); // Load every version as a major version for now - see http://code.google.com/p/alfresco-bulk-filesystem-import/issues/detail?id=84 + if(nodeState == NodeState.REPLACED) + { + versionService.deleteVersionHistory(nodeRef); + } + for (final ImportableItem.VersionedContentAndMetadata versionEntry : importableItem.getVersionEntries()) { MetadataLoader.Metadata metadata = loadMetadata(versionEntry); @@ -220,6 +223,13 @@ public abstract class AbstractNodeImporter implements NodeImporter if (logger.isDebugEnabled()) logger.debug("Creating head revision of node " + nodeRef.toString()); ImportableItem.ContentAndMetadata contentAndMetadata = importableItem.getHeadRevision(); MetadataLoader.Metadata metadata = loadMetadata(contentAndMetadata); + + // If cm:versionable isn't listed as one of the aspects for this node, add it - cm:versionable is required for nodes that have versions + if (!metadata.getAspects().contains(ContentModel.ASPECT_VERSIONABLE)) + { + if (logger.isWarnEnabled()) logger.warn("Metadata for file '" + getFileName(importableItem.getHeadRevision().getContentFile()) + "' was missing the cm:versionable aspect, yet it has " + importableItem.getVersionEntries().size() + " versions. Adding cm:versionable."); + metadata.addAspect(ContentModel.ASPECT_VERSIONABLE); + } importContentAndMetadata(nodeRef, importableItem.getHeadRevision(), metadata); versionService.createVersion(nodeRef, versionProperties); @@ -248,7 +258,7 @@ public abstract class AbstractNodeImporter implements NodeImporter nodeRef = fileFolderService.searchSimple(target, nodeName); - // If we didn't find an existing item, create a new node in the repo. + // If we didn't find an existing item, create a new node in the repo. if (nodeRef == null) { // But only if the content file exists - we don't create new nodes based on metadata-only importableItems diff --git a/source/java/org/alfresco/repo/bulkimport/impl/StreamingNodeImporterFactory.java b/source/java/org/alfresco/repo/bulkimport/impl/StreamingNodeImporterFactory.java index 94e2ac0cbf..ac99fae1a0 100644 --- a/source/java/org/alfresco/repo/bulkimport/impl/StreamingNodeImporterFactory.java +++ b/source/java/org/alfresco/repo/bulkimport/impl/StreamingNodeImporterFactory.java @@ -125,7 +125,7 @@ public class StreamingNodeImporterFactory extends AbstractNodeImporterFactory } else { - numVersionProperties = importImportableItemFile(result, importableItem, metadata); + numVersionProperties = importImportableItemFile(result, importableItem, metadata, nodeState); } importStatus.incrementNodesWritten(importableItem, isDirectory, nodeState, metadata.getProperties().size() + 4, numVersionProperties); diff --git a/source/test-java/org/alfresco/repo/bulkimport/impl/BulkImportTest.java b/source/test-java/org/alfresco/repo/bulkimport/impl/BulkImportTest.java index 4bf28cbab7..38393c8efa 100644 --- a/source/test-java/org/alfresco/repo/bulkimport/impl/BulkImportTest.java +++ b/source/test-java/org/alfresco/repo/bulkimport/impl/BulkImportTest.java @@ -375,4 +375,215 @@ public class BulkImportTest extends AbstractBulkImportTests assertEquals("This is version 1 of fileWithVersions.txt.", contentReader.getContentString()); } + /** + * MNT-9067: bulkimport "Replace existing files" option does not work when versioning is enabled + * + * @throws Throwable + */ + @Test + public void testMNT9067() throws Throwable + { + txn = transactionService.getUserTransaction(); + txn.begin(); + + NodeRef folderNode = topLevelFolder.getNodeRef(); + + //initial import + try + { + NodeImporter nodeImporter = streamingNodeImporterFactory.getNodeImporter(ResourceUtils.getFile("classpath:bulkimport3/initial")); + BulkImportParameters bulkImportParameters = new BulkImportParameters(); + bulkImportParameters.setTarget(folderNode); + bulkImportParameters.setReplaceExisting(true); + bulkImportParameters.setDisableRulesService(true); + bulkImportParameters.setBatchSize(40); + bulkImporter.bulkImport(bulkImportParameters, nodeImporter); + } + catch(Throwable e) + { + fail(e.getMessage()); + } + + txn.commit(); + txn = transactionService.getUserTransaction(); + txn.begin(); + + System.out.println(bulkImporter.getStatus()); + assertEquals(false, bulkImporter.getStatus().inProgress()); + + List files = getFiles(folderNode, null); + assertEquals("One file is expected to be imported:", 1, files.size()); + FileInfo file = files.get(0); + assertEquals("File name is not equal:", "fileWithVersions.txt", file.getName()); + + NodeRef fileNodeRef = file.getNodeRef(); + assertTrue("Imported file should be versioned:", versionService.isVersioned(fileNodeRef)); + + VersionHistory history = versionService.getVersionHistory(fileNodeRef); + assertEquals("Imported file should have 4 versions:", 4, history.getAllVersions().size()); + + + //replace versioned file with new versioned file + try + { + NodeImporter nodeImporter = streamingNodeImporterFactory.getNodeImporter(ResourceUtils.getFile("classpath:bulkimport3/replace_with_versioned")); + BulkImportParameters bulkImportParameters = new BulkImportParameters(); + bulkImportParameters.setTarget(folderNode); + bulkImportParameters.setReplaceExisting(true); + bulkImportParameters.setDisableRulesService(true); + bulkImportParameters.setBatchSize(40); + bulkImporter.bulkImport(bulkImportParameters, nodeImporter); + } + catch(Throwable e) + { + fail(e.getMessage()); + } + + System.out.println(bulkImporter.getStatus()); + assertEquals(false, bulkImporter.getStatus().inProgress()); + + txn.commit(); + txn = transactionService.getUserTransaction(); + txn.begin(); + + files = getFiles(folderNode, null); + assertEquals("One file is expected to be imported:", 1, files.size()); + file = files.get(0); + assertEquals("File name is not equal:", "fileWithVersions.txt", file.getName()); + + fileNodeRef = file.getNodeRef(); + assertTrue("Imported file should be versioned:", versionService.isVersioned(fileNodeRef)); + + history = versionService.getVersionHistory(fileNodeRef); + assertNotNull(history); + + + assertEquals("Imported file should have 5 versions:", 5, history.getAllVersions().size()); + + Version[] versions = history.getAllVersions().toArray(new Version[5]); + + //compare the content of each version + ContentReader contentReader; + contentReader = this.contentService.getReader(versions[0].getFrozenStateNodeRef(), ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is the final version of replaced on import fileWithVersions.txt.", contentReader.getContentString()); + + contentReader = this.contentService.getReader(versions[1].getFrozenStateNodeRef(), ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is version 4 of replaced on import fileWithVersions.txt.", contentReader.getContentString()); + + contentReader = this.contentService.getReader(versions[2].getFrozenStateNodeRef(), ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is version 3 of replaced on import fileWithVersions.txt.", contentReader.getContentString()); + + contentReader = this.contentService.getReader(versions[3].getFrozenStateNodeRef(), ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is version 2 of replaced on import fileWithVersions.txt.", contentReader.getContentString()); + + contentReader = this.contentService.getReader(versions[4].getFrozenStateNodeRef(), ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is version 1 of replaced on import fileWithVersions.txt.", contentReader.getContentString()); + + txn.commit(); + txn = transactionService.getUserTransaction(); + txn.begin(); + + //import non versioned file + try + { + NodeImporter nodeImporter = streamingNodeImporterFactory.getNodeImporter(ResourceUtils.getFile("classpath:bulkimport3/replace_with_non_versioned")); + BulkImportParameters bulkImportParameters = new BulkImportParameters(); + bulkImportParameters.setTarget(folderNode); + bulkImportParameters.setReplaceExisting(true); + bulkImportParameters.setDisableRulesService(true); + bulkImportParameters.setBatchSize(40); + bulkImporter.bulkImport(bulkImportParameters, nodeImporter); + } + catch(Throwable e) + { + fail(e.getMessage()); + } + + txn.commit(); + txn = transactionService.getUserTransaction(); + txn.begin(); + + System.out.println(bulkImporter.getStatus()); + assertEquals(false, bulkImporter.getStatus().inProgress()); + + files = getFiles(folderNode, null); + assertEquals("One file is expected to be imported:", 1, files.size()); + file = files.get(0); + assertEquals("File name is not equal:", "fileWithVersions.txt", file.getName()); + + fileNodeRef = file.getNodeRef(); + assertTrue("Imported file should be non versioned:", !versionService.isVersioned(fileNodeRef)); + + contentReader = this.contentService.getReader(fileNodeRef, ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is non versioned fileWithVersions.txt.", contentReader.getContentString()); + + txn.commit(); + txn = transactionService.getUserTransaction(); + txn.begin(); + + //use initial file again to replace non versioned file + try + { + NodeImporter nodeImporter = streamingNodeImporterFactory.getNodeImporter(ResourceUtils.getFile("classpath:bulkimport3/initial")); + BulkImportParameters bulkImportParameters = new BulkImportParameters(); + bulkImportParameters.setTarget(folderNode); + bulkImportParameters.setReplaceExisting(true); + bulkImportParameters.setDisableRulesService(true); + bulkImportParameters.setBatchSize(40); + bulkImporter.bulkImport(bulkImportParameters, nodeImporter); + } + catch(Throwable e) + { + fail(e.getMessage()); + } + + txn.commit(); + txn = transactionService.getUserTransaction(); + txn.begin(); + + System.out.println(bulkImporter.getStatus()); + assertEquals(false, bulkImporter.getStatus().inProgress()); + + files = getFiles(folderNode, null); + assertEquals("One file is expected to be imported:", 1, files.size()); + file = files.get(0); + assertEquals("File name is not equal:", "fileWithVersions.txt", file.getName()); + + fileNodeRef = file.getNodeRef(); + assertTrue("Imported file should be versioned:", versionService.isVersioned(fileNodeRef)); + + history = versionService.getVersionHistory(fileNodeRef); + assertNotNull(history); + + + assertEquals("Imported file should have 4 versions:", 4, history.getAllVersions().size()); + + versions = history.getAllVersions().toArray(new Version[4]); + + //compare the content of each version + + contentReader = this.contentService.getReader(versions[0].getFrozenStateNodeRef(), ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is the final version of fileWithVersions.txt.", contentReader.getContentString()); + + contentReader = this.contentService.getReader(versions[1].getFrozenStateNodeRef(), ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is version 3 of fileWithVersions.txt.", contentReader.getContentString()); + + contentReader = this.contentService.getReader(versions[2].getFrozenStateNodeRef(), ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is version 2 of fileWithVersions.txt.", contentReader.getContentString()); + + contentReader = this.contentService.getReader(versions[3].getFrozenStateNodeRef(), ContentModel.PROP_CONTENT); + assertNotNull(contentReader); + assertEquals("This is version 1 of fileWithVersions.txt.", contentReader.getContentString()); + + } + } diff --git a/source/test-resources/bulkimport3/initial/fileWithVersions.txt b/source/test-resources/bulkimport3/initial/fileWithVersions.txt new file mode 100644 index 0000000000..26409c0858 --- /dev/null +++ b/source/test-resources/bulkimport3/initial/fileWithVersions.txt @@ -0,0 +1 @@ +This is the final version of fileWithVersions.txt. \ No newline at end of file diff --git a/source/test-resources/bulkimport3/initial/fileWithVersions.txt.v1 b/source/test-resources/bulkimport3/initial/fileWithVersions.txt.v1 new file mode 100644 index 0000000000..443c2590e9 --- /dev/null +++ b/source/test-resources/bulkimport3/initial/fileWithVersions.txt.v1 @@ -0,0 +1 @@ +This is version 1 of fileWithVersions.txt. \ No newline at end of file diff --git a/source/test-resources/bulkimport3/initial/fileWithVersions.txt.v2 b/source/test-resources/bulkimport3/initial/fileWithVersions.txt.v2 new file mode 100644 index 0000000000..6f7c5ea9a8 --- /dev/null +++ b/source/test-resources/bulkimport3/initial/fileWithVersions.txt.v2 @@ -0,0 +1 @@ +This is version 2 of fileWithVersions.txt. \ No newline at end of file diff --git a/source/test-resources/bulkimport3/initial/fileWithVersions.txt.v3 b/source/test-resources/bulkimport3/initial/fileWithVersions.txt.v3 new file mode 100644 index 0000000000..9e50bb55a4 --- /dev/null +++ b/source/test-resources/bulkimport3/initial/fileWithVersions.txt.v3 @@ -0,0 +1 @@ +This is version 3 of fileWithVersions.txt. \ No newline at end of file diff --git a/source/test-resources/bulkimport3/replace_with_non_versioned/fileWithVersions.txt b/source/test-resources/bulkimport3/replace_with_non_versioned/fileWithVersions.txt new file mode 100644 index 0000000000..13bff5254c --- /dev/null +++ b/source/test-resources/bulkimport3/replace_with_non_versioned/fileWithVersions.txt @@ -0,0 +1 @@ +This is non versioned fileWithVersions.txt. \ No newline at end of file diff --git a/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt new file mode 100644 index 0000000000..1b6b7f9ccb --- /dev/null +++ b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt @@ -0,0 +1 @@ +This is the final version of replaced on import fileWithVersions.txt. \ No newline at end of file diff --git a/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v1 b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v1 new file mode 100644 index 0000000000..30e7b014d3 --- /dev/null +++ b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v1 @@ -0,0 +1 @@ +This is version 1 of replaced on import fileWithVersions.txt. \ No newline at end of file diff --git a/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v2 b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v2 new file mode 100644 index 0000000000..50c2926bae --- /dev/null +++ b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v2 @@ -0,0 +1 @@ +This is version 2 of replaced on import fileWithVersions.txt. \ No newline at end of file diff --git a/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v3 b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v3 new file mode 100644 index 0000000000..521f9e3448 --- /dev/null +++ b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v3 @@ -0,0 +1 @@ +This is version 3 of replaced on import fileWithVersions.txt. \ No newline at end of file diff --git a/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v4 b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v4 new file mode 100644 index 0000000000..7b1fba00b8 --- /dev/null +++ b/source/test-resources/bulkimport3/replace_with_versioned/fileWithVersions.txt.v4 @@ -0,0 +1 @@ +This is version 4 of replaced on import fileWithVersions.txt. \ No newline at end of file