/** A simple audit entry Currently we ignore filtering here. */ public void audit(String source, String description, NodeRef key, Object... args) { final AuditState auditInfo = new AuditState(auditConfiguration); AuditMode auditMode = AuditMode.UNSET; try { auditMode = onApplicationAudit(auditMode, auditInfo, source, description, key, args); if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS)) { RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { auditDAO.audit(auditInfo); return null; } }; transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, false); } } catch (Throwable t) { auditMode = onError(auditMode, auditInfo, t, source, description, key, args); if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.FAIL)) { try { RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { auditDAO.audit(auditInfo); return null; } }; transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, true); } catch (Throwable tt) { throw new AuditException("Failed to audit exception", new Object[] {tt}, t); } } throw new AuditException("Application audit failed", t); } }
/** Initialise - after bootstrap of schema and tenant admin service */ public void init() { PropertyCheck.mandatory(this, "dictionaryDAO", dictionaryDAO); PropertyCheck.mandatory(this, "contentService", contentService); PropertyCheck.mandatory(this, "nodeService", nodeService); PropertyCheck.mandatory(this, "tenantAdminService", tenantAdminService); PropertyCheck.mandatory(this, "namespaceService", namespaceService); PropertyCheck.mandatory(this, "messageService", messageService); PropertyCheck.mandatory(this, "transactionService", transactionService); PropertyCheck.mandatory(this, "policyComponent", policyComponent); if (onLoadDynamicModelDelegate == null) { onLoadDynamicModelDelegate = policyComponent.registerClassPolicy(DynamicModelPolicies.OnLoadDynamicModel.class); } transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Object>() { public Object execute() throws Exception { onDictionaryInit(); initMessages(); return (Object) null; } }, transactionService.isReadOnly(), false); }
/** * Internal audit of a method invocation * * @param mi - the method to audit * @return - the return object from the audited method * @throws Throwable - any Throwable that can be thrown by th audtied method. */ public Object auditImpl(MethodInvocation mi, boolean execute) throws Throwable { final AuditState auditInfo = new AuditState(auditConfiguration); // RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi); AuditMode auditMode = AuditMode.UNSET; try { Object o = null; auditMode = beforeInvocation(auditMode, auditInfo, mi); if (execute) { o = mi.proceed(); auditMode = postInvocation(auditMode, auditInfo, mi, o); } if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS)) { RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { auditDAO.audit(auditInfo); return null; } }; boolean requiresNew = (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_READ_WRITE); transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, requiresNew); } return o; } catch (Throwable t) { auditMode = onError(auditMode, auditInfo, mi, t); if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.FAIL)) { try { RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { auditDAO.audit(auditInfo); return null; } }; transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, true); } catch (Throwable tt) { throw new AuditException("Failed to audit exception", new Object[] {tt}, t); } } throw t; } }
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())); }
/** Initialise the dictionary, ensuring that a transaction is available */ @Override public void onDictionaryInit() { if (onLoadDynamicModelDelegate == null) { onLoadDynamicModelDelegate = policyComponent.registerClassPolicy(DynamicModelPolicies.OnLoadDynamicModel.class); } RetryingTransactionCallback<Void> initCallback = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { onDictionaryInitInTxn(); return null; } }; transactionService.getRetryingTransactionHelper().doInTransaction(initCallback, true, false); }
private void assertDocumentVersionAndName(final String versionLabel, final String name) { transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { Map<QName, Serializable> properties = getAndAssertProperties(document, versionLabel); assertEquals(name, properties.get(ContentModel.PROP_NAME)); return null; } }, true); }
/** * {@inheritDoc} * * @since 3.2 */ public Map<String, Serializable> recordAuditValues( String rootPath, Map<String, Serializable> values) { ParameterCheck.mandatory("rootPath", rootPath); AuditApplication.checkPathFormat(rootPath); if (values == null || values.isEmpty() || !isSourcePathMapped(rootPath)) { return Collections.emptyMap(); } // Build the key paths using the session root path Map<String, Serializable> pathedValues = new HashMap<String, Serializable>(values.size() * 2); for (Map.Entry<String, Serializable> entry : values.entrySet()) { String pathElement = entry.getKey(); String path = AuditApplication.buildPath(rootPath, pathElement); pathedValues.put(path, entry.getValue()); } // Translate the values map PathMapper pathMapper = auditModelRegistry.getAuditPathMapper(); final Map<String, Serializable> mappedValues = pathMapper.convertMap(pathedValues); if (mappedValues.isEmpty()) { return mappedValues; } // We have something to record. Start a transaction, if necessary TxnReadState txnState = AlfrescoTransactionSupport.getTransactionReadState(); switch (txnState) { case TXN_NONE: case TXN_READ_ONLY: // New transaction RetryingTransactionCallback<Map<String, Serializable>> callback = new RetryingTransactionCallback<Map<String, Serializable>>() { public Map<String, Serializable> execute() throws Throwable { return recordAuditValuesImpl(mappedValues); } }; return transactionService .getRetryingTransactionHelper() .doInTransaction(callback, false, true); case TXN_READ_WRITE: return recordAuditValuesImpl(mappedValues); default: throw new IllegalStateException("Unknown txn state: " + txnState); } }
@Override protected void tearDown() throws Exception { globalProperties.setProperty(AUTO_VERSION_PROPS_KEY, "false"); transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { if (null != parentFolder) { nodeService.deleteNode(parentFolder); } authenticationService.clearCurrentSecurityContext(); return null; } }); }
public void testAutoVersionIncrementOnPropertiesUpdateByLockOwnerAlf14584() throws Exception { final String name = generateDocumentName(DOCUMENT_NAME, "0.2"); transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { Map<QName, Serializable> properties = getAndAssertProperties(document, "0.1"); Serializable autoVersionProps = properties.get(ContentModel.PROP_AUTO_VERSION_PROPS); assertNotNull( ("Autoversion property is NULL! NodeRef = '" + document.toString() + "'"), autoVersionProps); assertTrue( ("Autoversion must be TRUE! NodeRef = '" + document.toString() + "'"), (Boolean) autoVersionProps); lockService.lock(document, LockType.WRITE_LOCK); LockStatus lockStatus = lockService.getLockStatus(document); assertFalse( ("Node with NodeRef = '" + document.toString() + "' must not be locked for " + AuthenticationUtil.getFullyAuthenticatedUser() + " user! The user is lock owner"), isLocked(document)); assertEquals(LockStatus.LOCK_OWNER, lockService.getLockStatus(document)); nodeService.setProperty(document, ContentModel.PROP_NAME, name); return null; } }); assertDocumentVersionAndName("0.2", name); }
private void loadData(final int maxCount) { final MutableInt doneCount = new MutableInt(0); // Batches of 1000 objects RetryingTransactionCallback<Integer> makeNodesCallback = new RetryingTransactionCallback<Integer>() { public Integer execute() throws Throwable { for (int i = 0; i < 1000; i++) { // We don't need to write anything String contentUrl = FileContentStore.createNewFileStoreUrl(); ContentData contentData = new ContentData(contentUrl, MimetypeMap.MIMETYPE_TEXT_PLAIN, 10, "UTF-8"); nodeHelper.makeNode(contentData); int count = doneCount.intValue(); count++; doneCount.setValue(count); // Do some reporting if (count % 1000 == 0) { System.out.println( String.format(" " + (new Date()) + "Total created: %6d", count)); } // Double check for shutdown if (vmShutdownListener.isVmShuttingDown()) { break; } } return maxCount; } }; int repetitions = (int) Math.floor((double) maxCount / 1000.0); for (int i = 0; i < repetitions; i++) { transactionService.getRetryingTransactionHelper().doInTransaction(makeNodesCallback); } }
@Override protected void setUp() throws Exception { globalProperties.setProperty(AUTO_VERSION_PROPS_KEY, "true"); transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { authenticationService.authenticate( ADMIN_CREDENTIAL, ADMIN_CREDENTIAL.toCharArray()); ResultSet query = null; NodeRef rootNode = null; try { query = searchService.query( StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, ROOT_NODE_TERM); rootNode = query.getNodeRef(0); } finally { if (null != query) { query.close(); } } Map<QName, Serializable> properties = new HashMap<QName, Serializable>(); properties.put(ContentModel.PROP_NAME, PARENT_FOLDER_NAME); parentFolder = nodeService .createNode( rootNode, ContentModel.ASSOC_CONTAINS, QName.createQName(ContentModel.USER_MODEL_URI, PARENT_FOLDER_NAME), ContentModel.TYPE_FOLDER, properties) .getChildRef(); properties.clear(); properties.put(ContentModel.PROP_NAME, DOCUMENT_NAME); document = nodeService .createNode( parentFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(ContentModel.USER_MODEL_URI, DOCUMENT_NAME), ContentModel.TYPE_CONTENT, properties) .getChildRef(); contentService .getWriter(document, ContentModel.PROP_CONTENT, true) .putContent(TEST_CONTENT_01); if (!nodeService.hasAspect(document, ContentModel.ASPECT_VERSIONABLE)) { Map<QName, Serializable> versionProperties = new HashMap<QName, Serializable>(); versionProperties.put(ContentModel.PROP_VERSION_LABEL, "0.1"); versionProperties.put(ContentModel.PROP_INITIAL_VERSION, true); versionProperties.put(ContentModel.PROP_VERSION_TYPE, VersionType.MINOR); nodeService.addAspect( document, ContentModel.ASPECT_VERSIONABLE, versionProperties); } return null; } }); }
public void testAutoVersionIncrementOnPropertiesUpdateAfterCheckInAlf14584() throws Exception { final String name02 = generateDocumentName(DOCUMENT_NAME, "0.2"); final String name11 = generateDocumentName(DOCUMENT_NAME, "1.1"); transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { Map<QName, Serializable> properties = getAndAssertProperties(document, "0.1"); Serializable autoVersionProps = properties.get(ContentModel.PROP_AUTO_VERSION_PROPS); assertNotNull( ("Autoversion property is NULL! NodeRef = '" + document.toString() + "'"), autoVersionProps); assertTrue( ("Autoversion must be TRUE! NodeRef = '" + document.toString() + "'"), (Boolean) autoVersionProps); nodeService.setProperty(document, ContentModel.PROP_NAME, name02); return null; } }); transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { Map<QName, Serializable> properties = getAndAssertProperties(document, "0.2"); assertEquals(name02, properties.get(ContentModel.PROP_NAME)); NodeRef workingCopy = checkOutCheckInService.checkout(document); contentService .getWriter(workingCopy, ContentModel.PROP_CONTENT, true) .putContent(TEST_CONTENT_10); Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(); versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR); document = checkOutCheckInService.checkin(workingCopy, versionProperties); return null; } }); assertDocumentVersionAndName("1.0", name02); transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { nodeService.setProperty(document, ContentModel.PROP_NAME, name11); return null; } }); assertDocumentVersionAndName("1.1", name11); }
public void testMultipleCheckoutsCheckInsWithPropChange() { // Note: this test assumes cm:autoVersionProps=true by default (refer to cm:versionableAspect in // contentModel.xml) // Create a new node ChildAssociationRef childAssocRef = nodeService.createNode( rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("test"), ContentModel.TYPE_CONTENT, null); final NodeRef testNodeRef = childAssocRef.getChildRef(); // Add the version aspect to the created node nodeService.addAspect(testNodeRef, ContentModel.ASPECT_VERSIONABLE, null); setComplete(); endTransaction(); // Checkout final NodeRef workingCopy1 = transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<NodeRef>() { public NodeRef execute() throws Exception { return cociService.checkout(testNodeRef); } }); // Change property and checkin transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Object>() { public Object execute() throws Exception { nodeService.setProperty(workingCopy1, ContentModel.PROP_AUTHOR, "author1"); Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(); versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version 1"); cociService.checkin(workingCopy1, versionProperties); return null; } }); // Checkout final NodeRef workingCopy2 = transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<NodeRef>() { public NodeRef execute() throws Exception { return cociService.checkout(testNodeRef); } }); // Change property and checkin transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Object>() { public Object execute() throws Exception { nodeService.setProperty(workingCopy2, ContentModel.PROP_AUTHOR, "author2"); Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(); versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version 2"); cociService.checkin(workingCopy2, versionProperties); return null; } }); // Checkout final NodeRef workingCopy3 = transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<NodeRef>() { public NodeRef execute() throws Exception { return cociService.checkout(testNodeRef); } }); // Change property and checkin transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Object>() { public Object execute() throws Exception { nodeService.setProperty(workingCopy3, ContentModel.PROP_AUTHOR, "author3"); Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(); versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version 3"); cociService.checkin(workingCopy3, versionProperties); return null; } }); }
/** * 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()); }