Java tutorial
/* * #%L * Alfresco Repository * %% * Copyright (C) 2005 - 2016 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.repo.transfer; import static org.mockito.Mockito.*; import java.io.ByteArrayInputStream; import java.io.File; import java.io.Serializable; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.alfresco.model.ContentModel; import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode; import org.alfresco.repo.transfer.manifest.TransferManifestHeader; import org.alfresco.repo.transfer.manifest.TransferManifestNode; import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode; import org.alfresco.repo.transfer.manifest.XMLTransferManifestWriter; import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.MutableAuthenticationService; import org.alfresco.service.cmr.transfer.TransferException; import org.alfresco.service.cmr.transfer.TransferProgress; import org.alfresco.service.cmr.transfer.TransferServicePolicies; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.alfresco.test_category.BaseSpringTestsCategory; import org.alfresco.test_category.OwnJVMTestsCategory; import org.alfresco.util.BaseAlfrescoSpringTest; import org.alfresco.util.GUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.experimental.categories.Category; import org.mockito.ArgumentCaptor; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.support.DefaultTransactionDefinition; /** * Unit test for RepoTransferReceiverImpl * * @author Brian Remmington */ @SuppressWarnings("deprecation") @Category(BaseSpringTestsCategory.class) public class RepoTransferReceiverImplTest extends BaseAlfrescoSpringTest { private static int fileCount = 0; private static final Log log = LogFactory.getLog(RepoTransferReceiverImplTest.class); private RepoTransferReceiverImpl receiver; private SearchService searchService; private String dummyContent; private byte[] dummyContentBytes; private NodeRef guestHome; private PolicyComponent policyComponent; @Override public void runBare() throws Throwable { preventTransaction(); super.runBare(); } /** * Called during the transaction setup */ protected void onSetUp() throws Exception { super.onSetUp(); System.out.println("java.io.tmpdir == " + System.getProperty("java.io.tmpdir")); // Get the required services this.nodeService = (NodeService) this.applicationContext.getBean("nodeService"); this.contentService = (ContentService) this.applicationContext.getBean("contentService"); this.authenticationService = (MutableAuthenticationService) this.applicationContext .getBean("authenticationService"); this.actionService = (ActionService) this.applicationContext.getBean("actionService"); this.transactionService = (TransactionService) this.applicationContext.getBean("transactionComponent"); this.authenticationComponent = (AuthenticationComponent) this.applicationContext .getBean("authenticationComponent"); this.receiver = (RepoTransferReceiverImpl) this.getApplicationContext().getBean("transferReceiver"); this.policyComponent = (PolicyComponent) this.getApplicationContext().getBean("policyComponent"); this.searchService = (SearchService) this.getApplicationContext().getBean("searchService"); this.dummyContent = "This is some dummy content."; this.dummyContentBytes = dummyContent.getBytes("UTF-8"); setTransactionDefinition(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW)); authenticationComponent.setSystemUserAsCurrentUser(); startNewTransaction(); String guestHomeQuery = "/app:company_home/app:guest_home"; ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery); assertEquals("", 1, guestHomeResult.length()); guestHome = guestHomeResult.getNodeRef(0); endTransaction(); } public void testDelete() { log.debug("start testDelete"); final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper(); final String uuid = GUID.generate(); class TestContext { ChildAssociationRef childAssoc; } ; RetryingTransactionCallback<TestContext> setupCB = new RetryingTransactionCallback<TestContext>() { @Override public TestContext execute() throws Throwable { TestContext tc = new TestContext(); ResultSet rs = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, "/app:company_home"); assertEquals(1, rs.length()); NodeRef companyHome = rs.getNodeRef(0); Map<QName, Serializable> props = new HashMap<QName, Serializable>(); props.put(ContentModel.PROP_NAME, uuid); tc.childAssoc = nodeService.createNode(companyHome, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.APP_MODEL_1_0_URI, uuid), ContentModel.TYPE_CONTENT, props); return tc; } }; final TestContext tc = tran.doInTransaction(setupCB, false, true); RetryingTransactionCallback<Void> deleteCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { nodeService.deleteNode(tc.childAssoc.getChildRef()); return null; } }; tran.doInTransaction(deleteCB, false, true); RetryingTransactionCallback<Void> validateCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { log.debug("Test that original node no longer exists..."); assertFalse(nodeService.exists(tc.childAssoc.getChildRef())); log.debug("PASS - Original node no longer exists."); NodeRef archiveNodeRef = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, tc.childAssoc.getChildRef().getId()); log.debug("Test that archive node exists..."); assertTrue(nodeService.exists(archiveNodeRef)); log.debug("PASS - Archive node exists."); return null; } }; tran.doInTransaction(validateCB, false, true); } /** * Tests start and end with regard to locking. * @throws Exception */ public void DISABLED_testStartAndEnd() throws Exception { log.debug("start testStartAndEnd"); RetryingTransactionHelper trx = transactionService.getRetryingTransactionHelper(); RetryingTransactionCallback<Void> cb = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { log.debug("about to call start"); String transferId = receiver.start("1234", true, receiver.getVersion()); File stagingFolder = null; try { System.out.println("TransferId == " + transferId); stagingFolder = receiver.getStagingFolder(transferId); assertTrue(receiver.getStagingFolder(transferId).exists()); NodeRef tempFolder = receiver.getTempFolder(transferId); assertNotNull("tempFolder is null", tempFolder); Thread.sleep(1000); try { receiver.start("1234", true, receiver.getVersion()); fail("Successfully started twice!"); } catch (TransferException ex) { // Expected } Thread.sleep(300); try { receiver.start("1234", true, receiver.getVersion()); fail("Successfully started twice!"); } catch (TransferException ex) { // Expected } try { receiver.end( new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate()).toString()); // fail("Successfully ended with transfer id that doesn't own lock."); } catch (TransferException ex) { // Expected } } finally { log.debug("about to call end"); receiver.end(transferId); /** * Check clean-up */ if (stagingFolder != null) { assertFalse(stagingFolder.exists()); } } return null; } }; long oldRefreshTime = receiver.getLockRefreshTime(); try { receiver.setLockRefreshTime(500); for (int i = 0; i < 5; i++) { log.info("test iteration:" + i); trx.doInTransaction(cb, false, true); } } finally { receiver.setLockRefreshTime(oldRefreshTime); } } /** * Tests start and end with regard to locking. * * Going to cut down the timeout to a very short period, the lock should expire * @throws Exception */ public void DISABLED_testLockTimeout() throws Exception { log.info("start testLockTimeout"); RetryingTransactionHelper trx = transactionService.getRetryingTransactionHelper(); /** * Simulates a client starting a transfer and then "going away"; */ RetryingTransactionCallback<Void> startWithoutAnythingElse = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { log.debug("about to call start"); String transferId = receiver.start("1234", true, receiver.getVersion()); return null; } }; RetryingTransactionCallback<Void> slowTransfer = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { log.debug("about to call start"); String transferId = receiver.start("1234", true, receiver.getVersion()); Thread.sleep(1000); receiver.saveSnapshot(transferId, null); fail("did not timeout"); return null; } }; long lockRefreshTime = receiver.getLockRefreshTime(); long lockTimeOut = receiver.getLockTimeOut(); try { receiver.setLockRefreshTime(500); receiver.setLockTimeOut(200); /** * This test simulates a client that starts a transfer and then "goes away". * We kludge the timeouts to far shorter than normal to make the test run in a reasonable time. */ for (int i = 0; i < 3; i++) { log.info("test iteration:" + i); trx.doInTransaction(startWithoutAnythingElse, false, true); Thread.sleep(1000); } try { trx.doInTransaction(slowTransfer, false, true); } catch (Exception e) { // Expect to go here. } } finally { receiver.setLockRefreshTime(lockRefreshTime); receiver.setLockTimeOut(lockTimeOut); } log.info("end testLockTimeout"); } public void testSaveContent() throws Exception { log.info("start testSaveContent"); final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper(); startNewTransaction(); try { String transferId = receiver.start("1234", true, receiver.getVersion()); try { String contentId = "mytestcontent"; receiver.saveContent(transferId, contentId, new ByteArrayInputStream(dummyContentBytes)); File contentFile = new File(receiver.getStagingFolder(transferId), contentId); assertTrue(contentFile.exists()); assertEquals(dummyContentBytes.length, contentFile.length()); } finally { receiver.end(transferId); } } finally { endTransaction(); } } public void testSaveSnapshot() throws Exception { log.info("start testSaveSnapshot"); final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper(); startNewTransaction(); try { String transferId = receiver.start("1234", true, receiver.getVersion()); File snapshotFile = null; try { TransferManifestNode node = createContentNode(); List<TransferManifestNode> nodes = new ArrayList<TransferManifestNode>(); nodes.add(node); String snapshot = createSnapshot(nodes); receiver.saveSnapshot(transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); File stagingFolder = receiver.getStagingFolder(transferId); snapshotFile = new File(stagingFolder, "snapshot.xml"); assertTrue(snapshotFile.exists()); assertEquals(snapshot.getBytes("UTF-8").length, snapshotFile.length()); } finally { receiver.end(transferId); if (snapshotFile != null) { assertFalse(snapshotFile.exists()); } } } finally { endTransaction(); } } public void testBasicCommit() throws Exception { log.info("start testBasicCommit"); final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper(); class TestContext { TransferManifestNode node = null; String transferId = null; } RetryingTransactionCallback<TestContext> setupCB = new RetryingTransactionCallback<TestContext>() { @Override public TestContext execute() throws Throwable { TestContext tc = new TestContext(); tc.node = createContentNode(); return tc; } }; final TestContext tc = tran.doInTransaction(setupCB, false, true); RetryingTransactionCallback<Void> doPrepareCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { tc.transferId = receiver.start("1234", true, receiver.getVersion()); List<TransferManifestNode> nodes = new ArrayList<TransferManifestNode>(); nodes.add(tc.node); String snapshot = createSnapshot(nodes); receiver.saveSnapshot(tc.transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); receiver.saveContent(tc.transferId, tc.node.getUuid(), new ByteArrayInputStream(dummyContentBytes)); return null; } }; RetryingTransactionCallback<Void> doCommitCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { receiver.commit(tc.transferId); return null; } }; RetryingTransactionCallback<Void> doEndCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { receiver.end(tc.transferId); return null; } }; try { tran.doInTransaction(doPrepareCB, false, true); tran.doInTransaction(doCommitCB, false, true); } finally { if (tc.transferId != null) { tran.doInTransaction(doEndCB, false, true); } } RetryingTransactionCallback<Void> doValidateCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { assertTrue(nodeService.exists(tc.node.getNodeRef())); nodeService.deleteNode(tc.node.getNodeRef()); return null; } }; tran.doInTransaction(doValidateCB, false, true); } /** * Test More Complex Commit * * @throws Exception */ public void testMoreComplexCommit() throws Exception { log.info("start testMoreComplexCommit"); final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper(); class TestContext { List<TransferManifestNode> nodes = new ArrayList<TransferManifestNode>(); TransferManifestNormalNode node1 = null; TransferManifestNormalNode node2 = null; TransferManifestNode node3 = null; TransferManifestNode node4 = null; TransferManifestNode node5 = null; TransferManifestNode node6 = null; TransferManifestNode node7 = null; TransferManifestNode node8 = null; TransferManifestNode node9 = null; TransferManifestNode node10 = null; TransferManifestNormalNode node11 = null; TransferManifestNode node12 = null; String transferId = null; } ; RetryingTransactionCallback<TestContext> setupCB = new RetryingTransactionCallback<TestContext>() { @Override public TestContext execute() throws Throwable { TestContext tc = new TestContext(); tc.node1 = createContentNode(); tc.nodes.add(tc.node1); tc.node2 = createContentNode(); tc.nodes.add(tc.node2); tc.node3 = createContentNode(); tc.nodes.add(tc.node3); tc.node4 = createContentNode(); tc.nodes.add(tc.node4); tc.node5 = createContentNode(); tc.nodes.add(tc.node5); tc.node6 = createContentNode(); tc.nodes.add(tc.node6); tc.node7 = createContentNode(); tc.nodes.add(tc.node7); tc.node8 = createFolderNode(); tc.nodes.add(tc.node8); tc.node9 = createFolderNode(); tc.nodes.add(tc.node9); tc.node10 = createFolderNode(); tc.nodes.add(tc.node10); tc.node11 = createFolderNode(); tc.nodes.add(tc.node11); tc.node12 = createFolderNode(); tc.nodes.add(tc.node12); associatePeers(tc.node1, tc.node2); moveNode(tc.node2, tc.node11); return tc; } }; final TestContext tc = tran.doInTransaction(setupCB, false, true); RetryingTransactionCallback<Void> doPrepareCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { tc.transferId = receiver.start("1234", true, receiver.getVersion()); String snapshot = createSnapshot(tc.nodes); receiver.saveSnapshot(tc.transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); for (TransferManifestNode node : tc.nodes) { receiver.saveContent(tc.transferId, node.getUuid(), new ByteArrayInputStream(dummyContentBytes)); } return null; } }; RetryingTransactionCallback<Void> doCommitCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { log.info("testMoreComplexCommit - commit"); receiver.commit(tc.transferId); log.info("testMoreComplexCommit - commited"); return null; } }; RetryingTransactionCallback<Void> doEndCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { // Needs to move elsewhere to allow other tests to pass. receiver.end(tc.transferId); return null; } }; try { tran.doInTransaction(doPrepareCB, false, true); tran.doInTransaction(doCommitCB, false, true); } finally { if (tc.transferId != null) { tran.doInTransaction(doEndCB, false, true); } } RetryingTransactionCallback<Void> validateCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { log.info("testMoreComplexCommit - validate nodes"); assertTrue(nodeService.getAspects(tc.node1.getNodeRef()).contains(ContentModel.ASPECT_ATTACHABLE)); assertFalse(nodeService.getSourceAssocs(tc.node2.getNodeRef(), ContentModel.ASSOC_ATTACHMENTS) .isEmpty()); for (TransferManifestNode node : tc.nodes) { assertTrue(nodeService.exists(node.getNodeRef())); } return null; } }; tran.doInTransaction(validateCB, false, true); } /** * Test Node Delete And Restore * * @throws Exception */ @SuppressWarnings("unchecked") public void testNodeDeleteAndRestore() throws Exception { log.info("start testNodeDeleteAndRestore"); final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper(); final TransferServicePolicies.OnEndInboundTransferPolicy mockedPolicyHandler = mock( TransferServicePolicies.OnEndInboundTransferPolicy.class); policyComponent.bindClassBehaviour(TransferServicePolicies.OnEndInboundTransferPolicy.QNAME, TransferModel.TYPE_TRANSFER_RECORD, new JavaBehaviour(mockedPolicyHandler, "onEndInboundTransfer", NotificationFrequency.EVERY_EVENT)); class TestContext { String transferId; TransferManifestNormalNode node1; TransferManifestNormalNode node2; TransferManifestNode node3; TransferManifestNode node4; TransferManifestNode node5; TransferManifestNode node6; TransferManifestNode node7; TransferManifestNode node8; TransferManifestNode node9; TransferManifestNode node10; TransferManifestNormalNode node11; TransferManifestNode node12; TransferManifestDeletedNode deletedNode8; TransferManifestDeletedNode deletedNode2; TransferManifestDeletedNode deletedNode11; List<TransferManifestNode> nodes; String errorMsgId; } ; RetryingTransactionCallback<TestContext> setupCB = new RetryingTransactionCallback<TestContext>() { @Override public TestContext execute() throws Throwable { TestContext tc = new TestContext(); tc.nodes = new ArrayList<TransferManifestNode>(); tc.node1 = createContentNode(); tc.nodes.add(tc.node1); tc.node2 = createContentNode(); tc.nodes.add(tc.node2); tc.node3 = createContentNode(); tc.nodes.add(tc.node3); tc.node4 = createContentNode(); tc.nodes.add(tc.node4); tc.node5 = createContentNode(); tc.nodes.add(tc.node5); tc.node6 = createContentNode(); tc.nodes.add(tc.node6); tc.node7 = createContentNode(); tc.nodes.add(tc.node7); tc.node8 = createFolderNode(); tc.nodes.add(tc.node8); tc.node9 = createFolderNode(); tc.nodes.add(tc.node9); tc.node10 = createFolderNode(); tc.nodes.add(tc.node10); tc.node11 = createFolderNode(); tc.nodes.add(tc.node11); tc.node12 = createFolderNode(); tc.nodes.add(tc.node12); associatePeers(tc.node1, tc.node2); moveNode(tc.node2, tc.node11); tc.deletedNode8 = createDeletedNode(tc.node8); tc.deletedNode2 = createDeletedNode(tc.node2); tc.deletedNode11 = createDeletedNode(tc.node11); return tc; } }; final TestContext tc = tran.doInTransaction(setupCB, false, true); RetryingTransactionCallback<Void> doFirstPrepareCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { tc.transferId = receiver.start("1234", true, receiver.getVersion()); String snapshot = createSnapshot(tc.nodes); log.debug(snapshot); receiver.saveSnapshot(tc.transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); for (TransferManifestNode node : tc.nodes) { receiver.saveContent(tc.transferId, node.getUuid(), new ByteArrayInputStream(dummyContentBytes)); } return null; } }; RetryingTransactionCallback<Void> doCommitCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { receiver.commit(tc.transferId); return null; } }; RetryingTransactionCallback<Void> doEndCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { // Needs to move elsewhere to allow other tests to pass. receiver.end(tc.transferId); return null; } }; RetryingTransactionCallback<Void> validateFirstCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { assertTrue(nodeService.getAspects(tc.node1.getNodeRef()).contains(ContentModel.ASPECT_ATTACHABLE)); assertFalse(nodeService.getSourceAssocs(tc.node2.getNodeRef(), ContentModel.ASSOC_ATTACHMENTS) .isEmpty()); ArgumentCaptor<String> transferIdCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<Set> createdNodesCaptor = ArgumentCaptor.forClass(Set.class); ArgumentCaptor<Set> updatedNodesCaptor = ArgumentCaptor.forClass(Set.class); ArgumentCaptor<Set> deletedNodesCaptor = ArgumentCaptor.forClass(Set.class); verify(mockedPolicyHandler, times(1)).onEndInboundTransfer(transferIdCaptor.capture(), createdNodesCaptor.capture(), updatedNodesCaptor.capture(), deletedNodesCaptor.capture()); assertEquals(tc.transferId, transferIdCaptor.getValue()); Set capturedCreatedNodes = createdNodesCaptor.getValue(); assertEquals(tc.nodes.size(), capturedCreatedNodes.size()); for (TransferManifestNode node : tc.nodes) { assertTrue(nodeService.exists(node.getNodeRef())); assertTrue(capturedCreatedNodes.contains(node.getNodeRef())); } return null; } }; /** * First transfer test here */ try { tran.doInTransaction(doFirstPrepareCB, false, true); //MNT-15847 ensure that all onEndInboundTransfer calls from setupCB are not // counted in validateFirstCB reset(mockedPolicyHandler); tran.doInTransaction(doCommitCB, false, true); tran.doInTransaction(validateFirstCB, false, true); } finally { if (tc.transferId != null) { tran.doInTransaction(doEndCB, false, true); } } /** * Second transfer this time with some deleted nodes, * * nodes 8, 2, and 11 (11 and 2 are parent/child) */ reset(mockedPolicyHandler); logger.debug("part 2 - transfer some deleted nodes"); RetryingTransactionCallback<Void> doSecondPrepareCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { // Now delete nodes 8, 2, and 11 (11 and 2 are parent/child) tc.transferId = receiver.start("1234", true, receiver.getVersion()); String snapshot = createSnapshot(Arrays .asList(new TransferManifestNode[] { tc.deletedNode8, tc.deletedNode2, tc.deletedNode11 })); log.debug(snapshot); receiver.saveSnapshot(tc.transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); return null; } }; RetryingTransactionCallback<Void> validateSecondCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { ArgumentCaptor<String> transferIdCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<Set> createdNodesCaptor = ArgumentCaptor.forClass(Set.class); ArgumentCaptor<Set> updatedNodesCaptor = ArgumentCaptor.forClass(Set.class); ArgumentCaptor<Set> deletedNodesCaptor = ArgumentCaptor.forClass(Set.class); verify(mockedPolicyHandler, times(1)).onEndInboundTransfer(transferIdCaptor.capture(), createdNodesCaptor.capture(), updatedNodesCaptor.capture(), deletedNodesCaptor.capture()); assertEquals(tc.transferId, transferIdCaptor.getValue()); Set capturedDeletedNodes = deletedNodesCaptor.getValue(); assertEquals(3, capturedDeletedNodes.size()); assertTrue(capturedDeletedNodes.contains(tc.deletedNode8.getNodeRef())); assertTrue(capturedDeletedNodes.contains(tc.deletedNode2.getNodeRef())); assertTrue(capturedDeletedNodes.contains(tc.deletedNode11.getNodeRef())); log.debug("Test success of transfer..."); TransferProgress progress = receiver.getProgressMonitor().getProgress(tc.transferId); assertEquals(TransferProgress.Status.COMPLETE, progress.getStatus()); NodeRef archiveNode8 = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, tc.node8.getNodeRef().getId()); NodeRef archiveNode2 = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, tc.node2.getNodeRef().getId()); NodeRef archiveNode11 = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, tc.node11.getNodeRef().getId()); assertTrue(nodeService.exists(archiveNode8)); assertTrue(nodeService.hasAspect(archiveNode8, ContentModel.ASPECT_ARCHIVED)); log.debug("Successfully tested existence of archive node: " + archiveNode8); assertTrue(nodeService.exists(archiveNode2)); assertTrue(nodeService.hasAspect(archiveNode2, ContentModel.ASPECT_ARCHIVED)); log.debug("Successfully tested existence of archive node: " + archiveNode2); assertTrue(nodeService.exists(archiveNode11)); assertTrue(nodeService.hasAspect(archiveNode11, ContentModel.ASPECT_ARCHIVED)); log.debug("Successfully tested existence of archive node: " + archiveNode11); log.debug("Successfully tested existence of all archive nodes"); log.debug("Testing existence of original node: " + tc.node8.getNodeRef()); assertFalse(nodeService.exists(tc.node8.getNodeRef())); log.debug("Testing existence of original node: " + tc.node2.getNodeRef()); assertFalse(nodeService.exists(tc.node2.getNodeRef())); log.debug("Testing existence of original node: " + tc.node11.getNodeRef()); assertFalse(nodeService.exists(tc.node11.getNodeRef())); log.debug("Successfully tested non-existence of all original nodes"); log.debug( "Progress indication: " + progress.getCurrentPosition() + "/" + progress.getEndPosition()); return null; } }; try { tran.doInTransaction(doSecondPrepareCB, false, true); tran.doInTransaction(doCommitCB, false, true); tran.doInTransaction(validateSecondCB, false, true); } finally { if (tc.transferId != null) { tran.doInTransaction(doEndCB, false, true); } } logger.debug("part 3 - restore orphan node which should fail"); System.out.println("Now try to restore orphan node 2."); /** * A third transfer. Expect an "orphan" failure, since its parent (node11) is deleted */ reset(mockedPolicyHandler); String errorMsgId = null; RetryingTransactionCallback<Void> doThirdPrepareCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { tc.transferId = receiver.start("1234", true, receiver.getVersion()); String snapshot = createSnapshot(Arrays.asList(new TransferManifestNode[] { tc.node2 })); log.debug(snapshot); receiver.saveSnapshot(tc.transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); receiver.saveContent(tc.transferId, tc.node2.getUuid(), new ByteArrayInputStream(dummyContentBytes)); return null; } }; RetryingTransactionCallback<Void> doCommitExpectingFailCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { try { receiver.commit(tc.transferId); fail("Expected an exception"); } catch (TransferException ex) { // Expected tc.errorMsgId = ex.getMsgId(); ArgumentCaptor<String> transferIdCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<Set> createdNodesCaptor = ArgumentCaptor.forClass(Set.class); ArgumentCaptor<Set> updatedNodesCaptor = ArgumentCaptor.forClass(Set.class); ArgumentCaptor<Set> deletedNodesCaptor = ArgumentCaptor.forClass(Set.class); verify(mockedPolicyHandler, times(1)).onEndInboundTransfer(transferIdCaptor.capture(), createdNodesCaptor.capture(), updatedNodesCaptor.capture(), deletedNodesCaptor.capture()); assertEquals(tc.transferId, transferIdCaptor.getValue()); assertTrue(createdNodesCaptor.getValue().isEmpty()); assertTrue(updatedNodesCaptor.getValue().isEmpty()); assertTrue(deletedNodesCaptor.getValue().isEmpty()); } return null; } }; RetryingTransactionCallback<Void> validateThirdCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { TransferProgress progress = receiver.getProgressMonitor().getProgress(tc.transferId); assertEquals(TransferProgress.Status.ERROR, progress.getStatus()); log.debug( "Progress indication: " + progress.getCurrentPosition() + "/" + progress.getEndPosition()); assertNotNull("Progress error", progress.getError()); assertTrue(progress.getError() instanceof Exception); assertTrue(tc.errorMsgId, tc.errorMsgId.contains("orphan")); return null; } }; try { tran.doInTransaction(doThirdPrepareCB, false, true); tran.doInTransaction(doCommitExpectingFailCB, false, true); } finally { if (tc.transferId != null) { tran.doInTransaction(doEndCB, false, true); } } tran.doInTransaction(validateThirdCB, false, true); log.debug("start testNodeDeleteAndRestore"); } /** * Test for fault raised as ALF-2772 * (https://issues.alfresco.com/jira/browse/ALF-2772) When transferring * nodes it shouldn't matter the order in which they appear in the snapshot. * That is to say, it shouldn't matter if a child node is listed before its * parent node. * * Typically this is true, but in the special case where the parent node is * being restored from the target's archive store then there is a fault. The * process should be: * * 1. Process child node * 2. Fail to find parent node * 3. Place child node in temporary location and mark as an orphan * 4. Process parent node * 5. Create node to correspond to parent node * 6. "Re-parent" orphaned child node with parent node * * However, in the case where the parent node is found in the target's * archive store, the process is actually: * * 1. Process child node * 2. Fail to find parent node * 3. Place child node in temporary location and mark as an orphan * 4. Process parent node * 5. Find corresponding parent node in archive store and restore it * 6. Update corresponding parent node * * Note that, in this case, we are not re-parenting the orphan as we should be. * * @throws Exception */ public void testJira_ALF_2772() throws Exception { log.debug("start testJira_ALF_2772"); final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper(); class TestContext { TransferManifestNormalNode node1 = null; TransferManifestNormalNode node2 = null; TransferManifestNormalNode node11 = null; TransferManifestDeletedNode deletedNode11 = null; String transferId = null; } ; RetryingTransactionCallback<TestContext> setupCB = new RetryingTransactionCallback<TestContext>() { @Override public TestContext execute() throws Throwable { TestContext tc = new TestContext(); tc.node1 = createContentNode(); tc.node2 = createContentNode(); tc.node11 = createFolderNode(); associatePeers(tc.node1, tc.node2); moveNode(tc.node2, tc.node11); tc.deletedNode11 = createDeletedNode(tc.node11); return tc; } }; final TestContext tc = tran.doInTransaction(setupCB, false, true); RetryingTransactionCallback<Void> doEndCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { // Needs to move elsewhere to allow other tests to pass. receiver.end(tc.transferId); return null; } }; RetryingTransactionCallback<Void> doFirstCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { tc.transferId = receiver.start("1234", true, receiver.getVersion()); List<TransferManifestNode> nodes = new ArrayList<TransferManifestNode>(); //First we'll just send a folder node nodes.add(tc.node11); String snapshot = createSnapshot(nodes); log.debug(snapshot); receiver.saveSnapshot(tc.transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); for (TransferManifestNode node : nodes) { receiver.saveContent(tc.transferId, node.getUuid(), new ByteArrayInputStream(dummyContentBytes)); } receiver.commit(tc.transferId); for (TransferManifestNode node : nodes) { assertTrue(nodeService.exists(node.getNodeRef())); } return null; } }; /** * First we'll just send a folder node */ try { tran.doInTransaction(doFirstCB, false, true); } finally { if (tc.transferId != null) { tran.doInTransaction(doEndCB, false, true); } } RetryingTransactionCallback<Void> doSecondCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { tc.transferId = receiver.start("1234", true, receiver.getVersion()); String snapshot = createSnapshot(Arrays.asList(new TransferManifestNode[] { tc.deletedNode11 })); log.debug(snapshot); receiver.saveSnapshot(tc.transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); receiver.commit(tc.transferId); return null; } }; RetryingTransactionCallback<Void> doValidateSecondCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { TransferProgress progress = receiver.getProgressMonitor().getProgress(tc.transferId); assertEquals(TransferProgress.Status.COMPLETE, progress.getStatus()); NodeRef archivedNodeRef = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, tc.deletedNode11.getNodeRef().getId()); assertTrue(nodeService.exists(archivedNodeRef)); assertTrue(nodeService.hasAspect(archivedNodeRef, ContentModel.ASPECT_ARCHIVED)); log.debug("Successfully tested existence of archive node: " + tc.deletedNode11.getNodeRef()); log.debug("Successfully tested existence of all archive nodes"); log.debug("Testing existence of original node: " + tc.node11.getNodeRef()); assertFalse(nodeService.exists(tc.node11.getNodeRef())); log.debug("Successfully tested non-existence of all original nodes"); log.debug( "Progress indication: " + progress.getCurrentPosition() + "/" + progress.getEndPosition()); return null; } }; /** * Then delete a folder node */ try { tran.doInTransaction(doSecondCB, false, true); tran.doInTransaction(doValidateSecondCB, false, true); } finally { if (tc.transferId != null) { tran.doInTransaction(doEndCB, false, true); } } /** * Finally we transfer node2 and node11 (in that order) */ RetryingTransactionCallback<Void> doThirdCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { tc.transferId = receiver.start("1234", true, receiver.getVersion()); String snapshot = createSnapshot(Arrays.asList(new TransferManifestNode[] { tc.node2, tc.node11 })); log.debug(snapshot); receiver.saveSnapshot(tc.transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); receiver.saveContent(tc.transferId, tc.node2.getUuid(), new ByteArrayInputStream(dummyContentBytes)); receiver.commit(tc.transferId); return null; } }; RetryingTransactionCallback<Void> doValidateThirdCB = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { return null; } }; /** * Then delete a folder node */ try { tran.doInTransaction(doThirdCB, false, true); tran.doInTransaction(doValidateThirdCB, false, true); } finally { if (tc.transferId != null) { tran.doInTransaction(doEndCB, false, true); } } } /** * Test for fault raised as MNT-11057 * (https://issues.alfresco.com/jira/browse/MNT-11057) Bug in replication process on Aliens. * * @throws Exception */ public void testMNT11057() throws Exception { String folder1Name = "H1"; String folder2Name = "H2"; String folder3Name = "H3"; //Step 1 transfer from repo A (H1 -> H2) setDefaultRollback(true); startNewTransaction(); String transferIdA1 = receiver.start("transferFromRepoA1", true, receiver.getVersion()); TransferManifestNormalNode folder1A1 = createFolderNode(folder1Name); TransferManifestNormalNode folder2A1 = createFolderNode(folder2Name); TransferManifestNormalNode folder3A1 = createFolderNode(folder3Name); moveNode(folder2A1, folder1A1); List<TransferManifestNode> nodesA1 = new ArrayList<TransferManifestNode>(); nodesA1.add(folder1A1); nodesA1.add(folder2A1); endTransaction(); this.setDefaultRollback(false); startNewTransaction(); try { String snapshot = createSnapshot(nodesA1, "repo A"); log.debug(snapshot); receiver.saveSnapshot(transferIdA1, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); for (TransferManifestNode node : nodesA1) { receiver.saveContent(transferIdA1, node.getUuid(), new ByteArrayInputStream(dummyContentBytes)); } receiver.commit(transferIdA1); for (TransferManifestNode node : nodesA1) { assertTrue(nodeService.exists(node.getNodeRef())); } } finally { receiver.end(transferIdA1); endTransaction(); } //Step 2 trasfer from repo B (H1 -> H3) setDefaultRollback(true); startNewTransaction(); String transferIdB1 = receiver.start("transferFromRepoB1", true, receiver.getVersion()); TransferManifestNormalNode folder1B1 = createFolderNode(folder1Name); TransferManifestNormalNode folder3B1 = createFolderNode(folder3Name); moveNode(folder3B1, folder1B1); List<TransferManifestNode> nodesB1 = new ArrayList<TransferManifestNode>(); nodesB1.add(folder1B1); nodesB1.add(folder3B1); endTransaction(); this.setDefaultRollback(false); startNewTransaction(); try { String snapshot = createSnapshot(nodesB1, "repo B"); log.debug(snapshot); receiver.saveSnapshot(transferIdB1, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); for (TransferManifestNode node : nodesB1) { receiver.saveContent(transferIdB1, node.getUuid(), new ByteArrayInputStream(dummyContentBytes)); } receiver.commit(transferIdB1); } finally { receiver.end(transferIdB1); endTransaction(); } assertTrue(nodeService.exists(folder1A1.getNodeRef())); log.info("has Alien"); log.info(nodeService.hasAspect(folder1A1.getNodeRef(), TransferModel.ASPECT_ALIEN)); assertTrue(nodeService.exists(folder2A1.getNodeRef())); log.info("has Alien"); assertFalse(nodeService.hasAspect(folder2A1.getNodeRef(), TransferModel.ASPECT_ALIEN)); assertFalse(nodeService.exists(folder1B1.getNodeRef())); assertTrue(nodeService.exists(folder3B1.getNodeRef())); log.info("has Alien"); assertTrue(nodeService.hasAspect(folder3B1.getNodeRef(), TransferModel.ASPECT_ALIEN)); startNewTransaction(); moveNode(folder3A1, folder1A1); moveNode(folder2A1, folder3A1); nodesA1 = new ArrayList<TransferManifestNode>(); nodesA1.add(folder1A1); nodesA1.add(folder3A1); nodesA1.add(folder2A1); endTransaction(); //Step 3 transfer from repo A again (H2 is moved to newly created H3 on A: H1 -> H3 -> H2) startNewTransaction(); try { String transferId = receiver.start("transferFromRepoA1Again", true, receiver.getVersion()); String snapshot = createSnapshot(nodesA1, "repo A"); log.debug(snapshot); receiver.saveSnapshot(transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); receiver.commit(transferId); } catch (Exception ex) { if (ex instanceof NullPointerException) { fail("Test of MNT-11057 failed: " + ex.getMessage()); } } finally { endTransaction(); } } public void testAsyncCommit() throws Exception { log.info("start testAsyncCommit"); this.setDefaultRollback(false); localTestAsyncCommit(); } private String localTestAsyncCommit() throws Exception, InterruptedException { startNewTransaction(); final String transferId = receiver.start("1234", true, receiver.getVersion()); endTransaction(); startNewTransaction(); final List<TransferManifestNode> nodes = new ArrayList<TransferManifestNode>(); final TransferManifestNormalNode node1 = createContentNode(); nodes.add(node1); final TransferManifestNormalNode node2 = createContentNode(); nodes.add(node2); TransferManifestNode node3 = createContentNode(); nodes.add(node3); TransferManifestNode node4 = createContentNode(); nodes.add(node4); TransferManifestNode node5 = createContentNode(); nodes.add(node5); TransferManifestNode node6 = createContentNode(); nodes.add(node6); TransferManifestNode node7 = createContentNode(); nodes.add(node7); TransferManifestNode node8 = createFolderNode(); nodes.add(node8); TransferManifestNode node9 = createFolderNode(); nodes.add(node9); TransferManifestNode node10 = createFolderNode(); nodes.add(node10); TransferManifestNormalNode node11 = createFolderNode(); nodes.add(node11); TransferManifestNode node12 = createFolderNode(); nodes.add(node12); associatePeers(node1, node2); moveNode(node2, node11); endTransaction(); String snapshot = createSnapshot(nodes); startNewTransaction(); receiver.saveSnapshot(transferId, new ByteArrayInputStream(snapshot.getBytes("UTF-8"))); endTransaction(); for (TransferManifestNode node : nodes) { startNewTransaction(); receiver.saveContent(transferId, node.getUuid(), new ByteArrayInputStream(dummyContentBytes)); endTransaction(); } startNewTransaction(); receiver.commitAsync(transferId); endTransaction(); log.debug("Posted request for commit"); TransferProgressMonitor progressMonitor = receiver.getProgressMonitor(); TransferProgress progress = null; while (progress == null || !TransferProgress.getTerminalStatuses().contains(progress.getStatus())) { Thread.sleep(500); startNewTransaction(); progress = progressMonitor.getProgress(transferId); endTransaction(); log.debug("Progress indication: " + progress.getStatus() + ": " + progress.getCurrentPosition() + "/" + progress.getEndPosition()); } assertEquals(TransferProgress.Status.COMPLETE, progress.getStatus()); startNewTransaction(); try { assertTrue(nodeService.getAspects(node1.getNodeRef()).contains(ContentModel.ASPECT_ATTACHABLE)); assertFalse(nodeService.getSourceAssocs(node2.getNodeRef(), ContentModel.ASSOC_ATTACHMENTS).isEmpty()); for (TransferManifestNode node : nodes) { assertTrue(nodeService.exists(node.getNodeRef())); } } finally { endTransaction(); } return transferId; } public void testAsyncCommitWithSummaryReport() throws Exception { log.info("start testAsyncCommitWithSummaryReport"); this.setDefaultRollback(false); Properties properties = (Properties) this.getApplicationContext().getBean("global-properties"); //save the value of this summary report property to restore later String prevValue = properties.getProperty(TransferCommons.TS_SIMPLE_REPORT); try { properties.put(TransferCommons.TS_SIMPLE_REPORT, Boolean.TRUE.toString()); assertTrue(Boolean.parseBoolean(properties.getProperty(TransferCommons.TS_SIMPLE_REPORT))); localTestDestinationReports(true); } finally { if (prevValue == null) { properties.remove(TransferCommons.TS_SIMPLE_REPORT); } else { properties.put(TransferCommons.TS_SIMPLE_REPORT, prevValue); } } } public void testAsyncCommitWithOutSummaryReport() throws Exception { log.info("start testAsyncCommitWithOutSummaryReport"); this.setDefaultRollback(false); this.setDefaultRollback(false); Properties properties = (Properties) this.getApplicationContext().getBean("global-properties"); //save the value of this summary report property to restore later String prevValue = properties.getProperty(TransferCommons.TS_SIMPLE_REPORT); try { properties.put(TransferCommons.TS_SIMPLE_REPORT, Boolean.FALSE.toString()); assertFalse(Boolean.parseBoolean(properties.getProperty(TransferCommons.TS_SIMPLE_REPORT))); localTestDestinationReports(false); } finally { if (prevValue == null) { properties.remove(TransferCommons.TS_SIMPLE_REPORT); } else { properties.put(TransferCommons.TS_SIMPLE_REPORT, prevValue); } } } private void localTestDestinationReports(boolean testAlsoForSummaryReport) throws Exception, InterruptedException { final String transferId = localTestAsyncCommit(); // check the destination report was generated and // check that the simplified destination transfer report was // generated FileFolderService fileFolderService = (FileFolderService) this.getApplicationContext() .getBean("fileFolderService"); NodeRef destinationReportNodeRef = new NodeRef(transferId); assertTrue(nodeService.exists(destinationReportNodeRef)); assertTrue(nodeService.getType(destinationReportNodeRef).equals(TransferModel.TYPE_TRANSFER_RECORD)); String destinationReportName = (String) nodeService.getProperties(destinationReportNodeRef) .get(ContentModel.PROP_NAME); String destinationReportWithoutExtension = destinationReportName.substring(0, destinationReportName.lastIndexOf(".")); NodeRef summaryReportsParentFolder = null; String summaryReportsLocation = "/app:company_home/app:dictionary/app:transfers/app:inbound_transfer_records"; //properties.getProperty("spaces.transfer_summary_report.location"); getting the property from the properties bean does not work summaryReportsParentFolder = getSummaryReportsParentFolder(summaryReportsLocation); assertTrue(fileFolderService.getFileInfo(summaryReportsParentFolder).isFolder()); FileInfo simplifiedReportFile = null; for (FileInfo fi : fileFolderService.list(summaryReportsParentFolder)) { if (fi.getName().startsWith(destinationReportWithoutExtension) && fi.getName().contains(TransferSummaryReportImpl._SIMPLE_REPORT)) { simplifiedReportFile = fi; } } if (testAlsoForSummaryReport) { assertNotNull(simplifiedReportFile); } else { assertNull(simplifiedReportFile); } } private NodeRef getSummaryReportsParentFolder(String transferSummaryReportLocation) { NodeRef reportParentFolder = null; log.debug("Trying to find transfer summary report records folder: " + transferSummaryReportLocation); ResultSet rs = null; try { rs = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, transferSummaryReportLocation); if (rs.length() > 0) { reportParentFolder = rs.getNodeRef(0); log.debug("Found transfer summary report records folder: " + reportParentFolder); } } finally { if (rs != null) { rs.close(); } } return reportParentFolder; } /** * @param nodeToDelete * @return */ private TransferManifestDeletedNode createDeletedNode(TransferManifestNode nodeToDelete) { TransferManifestDeletedNode deletedNode = new TransferManifestDeletedNode(); deletedNode.setNodeRef(nodeToDelete.getNodeRef()); deletedNode.setParentPath(nodeToDelete.getParentPath()); deletedNode.setPrimaryParentAssoc(nodeToDelete.getPrimaryParentAssoc()); deletedNode.setUuid(nodeToDelete.getUuid()); return deletedNode; } /** * move transfer node to new parent. * @param childNode * @param newParent */ private void moveNode(TransferManifestNormalNode childNode, TransferManifestNormalNode newParent) { List<ChildAssociationRef> currentParents = childNode.getParentAssocs(); List<ChildAssociationRef> newParents = new ArrayList<ChildAssociationRef>(); for (ChildAssociationRef parent : currentParents) { if (!parent.isPrimary()) { newParents.add(parent); } else { ChildAssociationRef newPrimaryAssoc = new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, newParent.getNodeRef(), parent.getQName(), parent.getChildRef(), true, -1); newParents.add(newPrimaryAssoc); childNode.setPrimaryParentAssoc(newPrimaryAssoc); Path newParentPath = new Path(); newParentPath.append(newParent.getParentPath()); newParentPath.append(new Path.ChildAssocElement(newParent.getPrimaryParentAssoc())); childNode.setParentPath(newParentPath); } } childNode.setParentAssocs(newParents); } private void associatePeers(TransferManifestNormalNode source, TransferManifestNormalNode target) { List<AssociationRef> currentReferencedPeers = source.getTargetAssocs(); if (currentReferencedPeers == null) { currentReferencedPeers = new ArrayList<AssociationRef>(); source.setTargetAssocs(currentReferencedPeers); } List<AssociationRef> currentRefereePeers = target.getSourceAssocs(); if (currentRefereePeers == null) { currentRefereePeers = new ArrayList<AssociationRef>(); target.setSourceAssocs(currentRefereePeers); } Set<QName> aspects = source.getAspects(); if (aspects == null) { aspects = new HashSet<QName>(); source.setAspects(aspects); } aspects.add(ContentModel.ASPECT_ATTACHABLE); AssociationRef newAssoc = new AssociationRef(null, source.getNodeRef(), ContentModel.ASSOC_ATTACHMENTS, target.getNodeRef()); currentRefereePeers.add(newAssoc); currentReferencedPeers.add(newAssoc); } private String createSnapshot(List<TransferManifestNode> nodes) throws Exception { return createSnapshot(nodes, "repo 1"); } private String createSnapshot(List<TransferManifestNode> nodes, String repoID) throws Exception { XMLTransferManifestWriter manifestWriter = new XMLTransferManifestWriter(); StringWriter output = new StringWriter(); manifestWriter.startTransferManifest(output); TransferManifestHeader header = new TransferManifestHeader(); header.setCreatedDate(new Date()); header.setNodeCount(nodes.size()); header.setRepositoryId(repoID); manifestWriter.writeTransferManifestHeader(header); for (TransferManifestNode node : nodes) { manifestWriter.writeTransferManifestNode(node); } manifestWriter.endTransferManifest(); return output.toString(); } /** * @return */ private TransferManifestNormalNode createContentNode(/*String transferId*/) throws Exception { TransferManifestNormalNode node = new TransferManifestNormalNode(); String uuid = GUID.generate(); NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, uuid); node.setNodeRef(nodeRef); node.setUuid(uuid); byte[] dummyContent = "This is some dummy content.".getBytes("UTF-8"); node.setType(ContentModel.TYPE_CONTENT); /** * Get guest home */ NodeRef parentFolder = guestHome; String nodeName = uuid + ".testnode" + getNameSuffix(); List<ChildAssociationRef> parents = new ArrayList<ChildAssociationRef>(); ChildAssociationRef primaryAssoc = new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, parentFolder, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, nodeName), node.getNodeRef(), true, -1); parents.add(primaryAssoc); node.setParentAssocs(parents); node.setParentPath(nodeService.getPath(parentFolder)); node.setPrimaryParentAssoc(primaryAssoc); Map<QName, Serializable> props = new HashMap<QName, Serializable>(); props.put(ContentModel.PROP_NODE_UUID, uuid); props.put(ContentModel.PROP_NAME, nodeName); ContentData contentData = new ContentData("/" + uuid, "text/plain", dummyContent.length, "UTF-8"); props.put(ContentModel.PROP_CONTENT, contentData); node.setProperties(props); return node; } private TransferManifestNormalNode createFolderNode() throws Exception { return createFolderNode(null); } private TransferManifestNormalNode createFolderNode(String folderName) throws Exception { TransferManifestNormalNode node = new TransferManifestNormalNode(); String uuid = GUID.generate(); NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, uuid); node.setNodeRef(nodeRef); node.setUuid(uuid); node.setType(ContentModel.TYPE_FOLDER); /** * Get guest home */ String guestHomeQuery = "/app:company_home/app:guest_home"; ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery); assertEquals("", 1, guestHomeResult.length()); NodeRef guestHome = guestHomeResult.getNodeRef(0); NodeRef parentFolder = guestHome; String nodeName = folderName == null ? uuid + ".folder" + getNameSuffix() : folderName; List<ChildAssociationRef> parents = new ArrayList<ChildAssociationRef>(); ChildAssociationRef primaryAssoc = new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, parentFolder, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, nodeName), node.getNodeRef(), true, -1); parents.add(primaryAssoc); node.setParentAssocs(parents); node.setParentPath(nodeService.getPath(parentFolder)); node.setPrimaryParentAssoc(primaryAssoc); Map<QName, Serializable> props = new HashMap<QName, Serializable>(); props.put(ContentModel.PROP_NODE_UUID, uuid); props.put(ContentModel.PROP_NAME, nodeName); node.setProperties(props); return node; } private String getNameSuffix() { return "" + fileCount++; } }