public void testImmediateRemoval() throws Exception { eagerCleaner.setEagerOrphanCleanup(false); final StoreRef storeRef = nodeService.createStore("test", getName() + "-" + GUID.generate()); RetryingTransactionCallback<ContentData> testCallback = new RetryingTransactionCallback<ContentData>() { public ContentData execute() throws Throwable { // Create some content NodeRef rootNodeRef = nodeService.getRootNode(storeRef); Map<QName, Serializable> properties = new HashMap<QName, Serializable>(13); properties.put(ContentModel.PROP_NAME, (Serializable) "test.txt"); NodeRef contentNodeRef = nodeService .createNode( rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTENT, properties) .getChildRef(); ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.putContent("INITIAL CONTENT"); ContentData contentData = writer.getContentData(); // Delete the first node nodeService.deleteNode(contentNodeRef); // Done return contentData; } }; ContentData contentData = transactionService.getRetryingTransactionHelper().doInTransaction(testCallback); // Make sure that the content URL still exists ContentReader reader = contentService.getRawReader(contentData.getContentUrl()); assertNotNull(reader); assertTrue("Content should not have been eagerly deleted.", reader.exists()); // fire the cleaner cleaner.setProtectDays(0); cleaner.execute(); reader = contentService.getRawReader(contentData.getContentUrl()); // the content should have disappeared as it is not in the database assertFalse("Unprotected content was not deleted", reader.exists()); assertTrue("Content listener was not called", deletedUrls.contains(reader.getContentUrl())); }
/** * Create ContentData set it on a Node, delete the Node, then set the ContentData on a new node * and check that the content is preserved during eager cleanup. */ public void testEagerCleanupDereferencing() throws Exception { eagerCleaner.setEagerOrphanCleanup(true); final StoreRef storeRef = nodeService.createStore("test", getName() + "-" + GUID.generate()); RetryingTransactionCallback<ContentData> testCallback = new RetryingTransactionCallback<ContentData>() { public ContentData execute() throws Throwable { // Create some content NodeRef rootNodeRef = nodeService.getRootNode(storeRef); Map<QName, Serializable> properties = new HashMap<QName, Serializable>(13); properties.put(ContentModel.PROP_NAME, (Serializable) "test.txt"); NodeRef contentNodeRef = nodeService .createNode( rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTENT, properties) .getChildRef(); ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.putContent("INITIAL CONTENT"); ContentData contentData = writer.getContentData(); // Delete the first node nodeService.deleteNode(contentNodeRef); ContentReader reader = contentService.getRawReader(contentData.getContentUrl()); assertNotNull(reader); assertTrue("Content was cleaned before end of transaction", reader.exists()); // Make a new copy using the same ContentData properties.put(ContentModel.PROP_NAME, (Serializable) "test2.txt"); properties.put(ContentModel.PROP_CONTENT, contentData); contentNodeRef = nodeService .createNode( rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTENT, properties) .getChildRef(); reader = contentService.getRawReader(contentData.getContentUrl()); assertNotNull(reader); assertTrue("Content was cleaned before end of transaction", reader.exists()); // Done return contentData; } }; ContentData contentData = transactionService.getRetryingTransactionHelper().doInTransaction(testCallback); // Make sure that the content URL still exists ContentReader reader = contentService.getRawReader(contentData.getContentUrl()); assertNotNull(reader); assertTrue( "Content was cleaned despite being re-referenced in the transaction", reader.exists()); }
public void testEagerCleanupOnCommit() throws Exception { eagerCleaner.setEagerOrphanCleanup(true); // Create a new file RetryingTransactionCallback<NodeRef> makeContentCallback = new RetryingTransactionCallback<NodeRef>() { public NodeRef execute() throws Throwable { // Create some content StoreRef storeRef = nodeService.createStore("test", "testEagerCleanupOnCommit-" + GUID.generate()); NodeRef rootNodeRef = nodeService.getRootNode(storeRef); Map<QName, Serializable> properties = Collections.singletonMap(ContentModel.PROP_NAME, (Serializable) "test.txt"); NodeRef contentNodeRef = nodeService .createNode( rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTENT, properties) .getChildRef(); ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.putContent("INITIAL CONTENT"); // Done return contentNodeRef; } }; final NodeRef contentNodeRef = transactionService.getRetryingTransactionHelper().doInTransaction(makeContentCallback); ContentReader contentReader = contentService.getReader(contentNodeRef, ContentModel.PROP_CONTENT); assertTrue("Expect content to exist", contentReader.exists()); // Now update the node, but force a failure i.e. txn rollback final List<String> newContentUrls = new ArrayList<String>(); RetryingTransactionCallback<String> failUpdateCallback = new RetryingTransactionCallback<String>() { public String execute() throws Throwable { ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.putContent("CONTENT FOR FAIL"); // This will have updated the metadata, so we can fail now newContentUrls.add(writer.getContentUrl()); // Done throw new RuntimeException("FAIL"); } }; try { transactionService.getRetryingTransactionHelper().doInTransaction(failUpdateCallback); fail("Transaction was meant to fail"); } catch (RuntimeException e) { if (e.getMessage().equals("FAIL")) { // Expected } else { // Ooops throw e; } } // Make sure that the new content is not there // The original content must still be there assertEquals("Expected one content URL to play with", 1, newContentUrls.size()); ContentReader readerMissing = contentService.getRawReader(newContentUrls.get(0)); assertFalse("Newly created content should have been removed.", readerMissing.exists()); assertTrue("Original content should still be there.", contentReader.exists()); // Now update the node successfully RetryingTransactionCallback<String> successUpdateCallback = new RetryingTransactionCallback<String>() { public String execute() throws Throwable { ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.putContent("CONTENT FOR SUCCESS"); // Done return writer.getContentUrl(); } }; String newContentUrl = transactionService.getRetryingTransactionHelper().doInTransaction(successUpdateCallback); // Make sure that the new content is there // The original content was disposed of ContentReader contentReaderNew = contentService.getRawReader(newContentUrl); assertTrue("Newly created content should be present.", contentReaderNew.exists()); assertFalse("Original content should have been removed.", contentReader.exists()); // Now delete the node RetryingTransactionCallback<Object> deleteNodeCallback = new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { nodeService.deleteNode(contentNodeRef); // Done return null; } }; transactionService.getRetryingTransactionHelper().doInTransaction(deleteNodeCallback); // The new content must have disappeared assertFalse("Newly created content should be removed.", contentReaderNew.exists()); }