From 37638a9aa27b9a96360ea93c9151e543001931bc Mon Sep 17 00:00:00 2001 From: Adina Ababei Date: Tue, 2 Jun 2020 13:09:00 +0300 Subject: [PATCH] REPO-5163: Added CMIS integration test for node downloaded event (#1012) Co-authored-by: Chris Shields Co-authored-by: Sara Aspery --- .../repo/node/AbstractNodeServiceImpl.java | 188 ++++++++--------- .../event2/AbstractContextAwareRepoEvent.java | 4 + .../repo/event2/DownloadRepoEventIT.java | 196 ++++++++++++++++++ .../repo/event2/RepoEvent2ITSuite.java | 3 +- 4 files changed, 296 insertions(+), 95 deletions(-) create mode 100644 src/test/java/org/alfresco/repo/event2/DownloadRepoEventIT.java diff --git a/src/main/java/org/alfresco/repo/node/AbstractNodeServiceImpl.java b/src/main/java/org/alfresco/repo/node/AbstractNodeServiceImpl.java index cd4c8dd5b1..9cca9aa110 100644 --- a/src/main/java/org/alfresco/repo/node/AbstractNodeServiceImpl.java +++ b/src/main/java/org/alfresco/repo/node/AbstractNodeServiceImpl.java @@ -1,28 +1,28 @@ -/* - * #%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 . - * #L% - */ +/* + * #%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 . + * #L% + */ package org.alfresco.repo.node; import java.io.Serializable; @@ -197,13 +197,13 @@ public abstract class AbstractNodeServiceImpl implements NodeService public int hashCode() { return uuid.hashCode(); - } - - /** - * Registers the node policies as well as node indexing behaviour - */ - public void init() - { + } + + /** + * Registers the node policies as well as node indexing behaviour + */ + public void init() + { // Register the various policies beforeCreateStoreDelegate = policyComponent.registerClassPolicy(NodeServicePolicies.BeforeCreateStorePolicy.class); onCreateStoreDelegate = policyComponent.registerClassPolicy(NodeServicePolicies.OnCreateStorePolicy.class); @@ -310,13 +310,13 @@ public abstract class AbstractNodeServiceImpl implements NodeService // execute policy for node type and aspects NodeServicePolicies.OnCreateNodePolicy policy = onCreateNodeDelegate.get(childNodeRef, qnames); policy.onCreateNode(childAssocRef); - } - - /** - * @see NodeServicePolicies.BeforeMoveNodePolicy#beforeMoveNode(ChildAssociationRef, NodeRef) - */ - protected void invokeBeforeMoveNode(ChildAssociationRef oldChildAssocRef, NodeRef newParentRef) - { + } + + /** + * @see NodeServicePolicies.BeforeMoveNodePolicy#beforeMoveNode(ChildAssociationRef, NodeRef) + */ + protected void invokeBeforeMoveNode(ChildAssociationRef oldChildAssocRef, NodeRef newParentRef) + { NodeRef childNodeRef = oldChildAssocRef.getChildRef(); if (ignorePolicy(childNodeRef)) @@ -416,13 +416,13 @@ public abstract class AbstractNodeServiceImpl implements NodeService // execute policy for node type and aspects NodeServicePolicies.BeforeSetNodeTypePolicy policy = beforeSetNodeTypeDelegate.get(nodeRef, qnames); policy.beforeSetNodeType(nodeRef, oldType, newType); - } - - /** - * @see NodeServicePolicies.OnUpdatePropertiesPolicy#onUpdateProperties(NodeRef, Map, Map) - */ - protected void invokeOnUpdateProperties( - NodeRef nodeRef, + } + + /** + * @see NodeServicePolicies.OnUpdatePropertiesPolicy#onUpdateProperties(NodeRef, Map, Map) + */ + protected void invokeOnUpdateProperties( + NodeRef nodeRef, Map before, Map after) { @@ -489,13 +489,13 @@ public abstract class AbstractNodeServiceImpl implements NodeService // execute policy for node type and aspects NodeServicePolicies.BeforeDeleteNodePolicy policy = beforeDeleteNodeDelegate.get(nodeRef, qnames); policy.beforeDeleteNode(nodeRef); - } - - /** - * @see NodeServicePolicies.BeforeArchiveNodePolicy - */ - protected void invokeBeforeArchiveNode(NodeRef nodeRef) - { + } + + /** + * @see NodeServicePolicies.BeforeArchiveNodePolicy + */ + protected void invokeBeforeArchiveNode(NodeRef nodeRef) + { if (ignorePolicy(nodeRef)) { return; @@ -506,13 +506,13 @@ public abstract class AbstractNodeServiceImpl implements NodeService // execute policy for node type and aspects NodeServicePolicies.BeforeArchiveNodePolicy policy = beforeArchiveNodeDelegate.get(nodeRef, qnames); policy.beforeArchiveNode(nodeRef); - } - - /** - * @see NodeServicePolicies.OnDeleteNodePolicy#onDeleteNode(ChildAssociationRef, boolean) - */ - protected void invokeOnDeleteNode(ChildAssociationRef childAssocRef, QName childNodeTypeQName, Set childAspectQnames, boolean isArchivedNode) - { + } + + /** + * @see NodeServicePolicies.OnDeleteNodePolicy#onDeleteNode(ChildAssociationRef, boolean) + */ + protected void invokeOnDeleteNode(ChildAssociationRef childAssocRef, QName childNodeTypeQName, Set childAspectQnames, boolean isArchivedNode) + { NodeRef childNodeRef = childAssocRef.getChildRef(); Set qnames = null; @@ -540,13 +540,13 @@ public abstract class AbstractNodeServiceImpl implements NodeService NodeServicePolicies.OnDeleteNodePolicy policy = onDeleteNodeDelegate.get(childAssocRef.getChildRef(), qnames); policy.onDeleteNode(childAssocRef, isArchivedNode); } - } - - /** - * @see NodeServicePolicies.OnRestoreNodePolicy#onRestoreNode(ChildAssociationRef) - */ - protected void invokeOnRestoreNode(ChildAssociationRef childAssocRef) - { + } + + /** + * @see NodeServicePolicies.OnRestoreNodePolicy#onRestoreNode(ChildAssociationRef) + */ + protected void invokeOnRestoreNode(ChildAssociationRef childAssocRef) + { NodeRef childNodeRef = childAssocRef.getChildRef(); // get qnames to invoke against Set qnames = getTypeAndAspectQNames(childNodeRef); @@ -582,13 +582,13 @@ public abstract class AbstractNodeServiceImpl implements NodeService NodeServicePolicies.OnAddAspectPolicy policy = onAddAspectDelegate.get(nodeRef, aspectTypeQName); policy.onAddAspect(nodeRef, aspectTypeQName); - } - - /** - * @see NodeServicePolicies.BeforeRemoveAspectPolicy#beforeRemoveAspect(NodeRef, - * QName) - */ - protected void invokeBeforeRemoveAspect(NodeRef nodeRef, QName aspectTypeQName) + } + + /** + * @see NodeServicePolicies.BeforeRemoveAspectPolicy#beforeRemoveAspect(NodeRef, + * QName) + */ + protected void invokeBeforeRemoveAspect(NodeRef nodeRef, QName aspectTypeQName) { if (ignorePolicy(nodeRef)) { @@ -612,13 +612,13 @@ public abstract class AbstractNodeServiceImpl implements NodeService NodeServicePolicies.OnRemoveAspectPolicy policy = onRemoveAspectDelegate.get(nodeRef, aspectTypeQName); policy.onRemoveAspect(nodeRef, aspectTypeQName); - } - - /** - * @see NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(ChildAssociationRef, boolean) - */ - protected void invokeOnCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode) - { + } + + /** + * @see NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(ChildAssociationRef, boolean) + */ + protected void invokeOnCreateChildAssociation(ChildAssociationRef childAssocRef, boolean isNewNode) + { // Get the parent reference and the assoc type qName NodeRef parentNodeRef = childAssocRef.getParentRef(); @@ -673,13 +673,13 @@ public abstract class AbstractNodeServiceImpl implements NodeService // execute policy for node type and aspects NodeServicePolicies.OnDeleteChildAssociationPolicy policy = onDeleteChildAssociationDelegate.get(parentNodeRef, qnames, assocTypeQName); policy.onDeleteChildAssociation(childAssocRef); - } - - /** - * @see NodeServicePolicies.OnCreateAssociationPolicy#onCreateAssociation(AssociationRef) - */ - protected void invokeOnCreateAssociation(AssociationRef nodeAssocRef) - { + } + + /** + * @see NodeServicePolicies.OnCreateAssociationPolicy#onCreateAssociation(AssociationRef) + */ + protected void invokeOnCreateAssociation(AssociationRef nodeAssocRef) + { NodeRef sourceNodeRef = nodeAssocRef.getSourceRef(); if (ignorePolicy(sourceNodeRef)) @@ -814,12 +814,12 @@ public abstract class AbstractNodeServiceImpl implements NodeService } /** - * Sets the default property values - * - * @param classDefinition the model type definition for which to get defaults - */ - protected Map getDefaultProperties(ClassDefinition classDefinition) - { + * Sets the default property values + * + * @param classDefinition the model type definition for which to get defaults + */ + protected Map getDefaultProperties(ClassDefinition classDefinition) + { PropertyMap properties = new PropertyMap(); for (Map.Entry entry : classDefinition.getDefaultValues().entrySet()) { diff --git a/src/test/java/org/alfresco/repo/event2/AbstractContextAwareRepoEvent.java b/src/test/java/org/alfresco/repo/event2/AbstractContextAwareRepoEvent.java index f93da6a218..392a1a3355 100644 --- a/src/test/java/org/alfresco/repo/event2/AbstractContextAwareRepoEvent.java +++ b/src/test/java/org/alfresco/repo/event2/AbstractContextAwareRepoEvent.java @@ -35,6 +35,7 @@ import java.util.List; import javax.jms.ConnectionFactory; import org.alfresco.model.ContentModel; +import org.alfresco.opencmis.CMISConnector; import org.alfresco.repo.event.databind.ObjectMapperFactory; import org.alfresco.repo.event.v1.model.EventData; import org.alfresco.repo.event.v1.model.NodeResource; @@ -84,6 +85,9 @@ public abstract class AbstractContextAwareRepoEvent extends BaseSpringTest private static boolean isCamelConfigured; + @Autowired + protected CMISConnector cmisConnector; + @Autowired protected RetryingTransactionHelper retryingTransactionHelper; diff --git a/src/test/java/org/alfresco/repo/event2/DownloadRepoEventIT.java b/src/test/java/org/alfresco/repo/event2/DownloadRepoEventIT.java new file mode 100644 index 0000000000..052a8634c6 --- /dev/null +++ b/src/test/java/org/alfresco/repo/event2/DownloadRepoEventIT.java @@ -0,0 +1,196 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2020 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 . + * #L% + */ + +package org.alfresco.repo.event2; + +import org.alfresco.model.ContentModel; +import org.alfresco.opencmis.dictionary.CMISNodeInfo; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.event.v1.model.EventData; +import org.alfresco.repo.event.v1.model.NodeResource; +import org.alfresco.repo.event.v1.model.RepoEvent; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.NodeRef; +import org.junit.Before; +import org.junit.Test; + +/** + * @author Adina Ababei + */ +public class DownloadRepoEventIT extends AbstractContextAwareRepoEvent +{ + private ContentService contentService; + + @Before + public void setup() + { + contentService = (ContentService) applicationContext.getBean("contentService"); + } + + @Test + public void testDownload() + { + final NodeRef nodeRef = createNode(ContentModel.TYPE_CONTENT); + + // node.Created event should be generated + RepoEvent resultRepoEvent = getRepoEvent(1); + assertEquals("Wrong repo event type.", EventType.NODE_CREATED.getType(), resultRepoEvent.getType()); + + retryingTransactionHelper.doInTransaction(() -> { + ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.TYPE_CONTENT, + true); + writer.setMimetype(MimetypeMap.MIMETYPE_PDF); + writer.setEncoding("UTF-8"); + writer.putContent("test content"); + return null; + }); + + // node.Updated event should be generated + resultRepoEvent = getRepoEvent(2); + assertEquals("Wrong repo event type.", EventType.NODE_UPDATED.getType(), resultRepoEvent.getType()); + + retryingTransactionHelper.doInTransaction(() -> { + CMISNodeInfo cmisNodeInfo = cmisConnector.createNodeInfo(nodeRef); + cmisConnector.getContentStream(cmisNodeInfo, null, null, null); + return null; + }); + + // we should have 3 events: node.Created, node.Updated, node.Downloaded + checkNumOfEvents(3); + + // node.Downloaded event should be generated + RepoEvent downloadedRepoEvent = getRepoEvent(3); + assertEquals("Wrong repo event type.", EventType.NODE_DOWNLOADED.getType(), downloadedRepoEvent.getType()); + assertEquals(EventData.JSON_SCHEMA, downloadedRepoEvent.getDataschema()); + assertNotNull("The event should not have null id", downloadedRepoEvent.getId()); + assertNotNull("The event should not have null time", downloadedRepoEvent.getTime()); + + NodeResource nodeResource = downloadedRepoEvent.getData().getResource(); + assertNotNull("Resource ID is null", nodeResource.getId()); + assertNotNull("Default aspects were not added. ", nodeResource.getAspectNames()); + assertNotNull("Missing createdByUser property.", nodeResource.getCreatedByUser()); + assertNotNull("Missing createdAt property.", nodeResource.getCreatedAt()); + assertNotNull("Missing modifiedByUser property.", nodeResource.getModifiedByUser()); + assertNotNull("Missing modifiedAt property.", nodeResource.getModifiedAt()); + assertNotNull("Missing node resource properties", nodeResource.getProperties()); + assertTrue("Incorrect value for isFile field", nodeResource.isFile()); + assertFalse("Incorrect value for isFolder files", nodeResource.isFolder()); + assertNull("ResourceBefore is not null", downloadedRepoEvent.getData().getResourceBefore()); + } + + @Test + public void testDownloadTwiceInTheSameTransaction() + { + final NodeRef nodeRef = createNode(ContentModel.TYPE_CONTENT); + + // node.Created event should be generated + RepoEvent resultRepoEvent = getRepoEvent(1); + assertEquals("Wrong repo event type.", EventType.NODE_CREATED.getType(), resultRepoEvent.getType()); + + retryingTransactionHelper.doInTransaction(() -> { + ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.TYPE_CONTENT, + true); + writer.setMimetype(MimetypeMap.MIMETYPE_PDF); + writer.setEncoding("UTF-8"); + writer.putContent("test content"); + return null; + }); + + // node.Updated event should be generated + resultRepoEvent = getRepoEvent(2); + assertEquals("Wrong repo event type.", EventType.NODE_UPDATED.getType(), resultRepoEvent.getType()); + + retryingTransactionHelper.doInTransaction(() -> { + CMISNodeInfo cmisNodeInfo = cmisConnector.createNodeInfo(nodeRef); + cmisConnector.getContentStream(cmisNodeInfo, null, null, null); + cmisConnector.getContentStream(cmisNodeInfo, null, null, null); + return null; + }); + + // we should have 3 events: node.Created, node.Updated, node.Downloaded + checkNumOfEvents(3); + + RepoEvent downloadedRepoEvent = getRepoEvent(3); + assertEquals("Wrong repo event type.", EventType.NODE_DOWNLOADED.getType(), downloadedRepoEvent.getType()); + assertEquals("Downloaded event does not have the correct id", + getNodeResource(resultRepoEvent).getId(), + getNodeResource(downloadedRepoEvent).getId()); + assertNull("ResourceBefore field is not null", downloadedRepoEvent.getData().getResourceBefore()); + } + + @Test + public void testDownloadEventTwiceInDifferentTransactions() + { + final NodeRef nodeRef = createNode(ContentModel.TYPE_CONTENT); + + // node.Created event should be generated + RepoEvent resultRepoEvent = getRepoEvent(1); + assertEquals("Wrong repo event type.", EventType.NODE_CREATED.getType(), resultRepoEvent.getType()); + + retryingTransactionHelper.doInTransaction(() -> { + ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.TYPE_CONTENT, + true); + writer.setMimetype(MimetypeMap.MIMETYPE_PDF); + writer.setEncoding("UTF-8"); + writer.putContent("test content"); + return null; + }); + + // node.Updated event should be generated + resultRepoEvent = getRepoEvent(2); + assertEquals("Wrong repo event type.", EventType.NODE_UPDATED.getType(), resultRepoEvent.getType()); + + retryingTransactionHelper.doInTransaction(() -> { + CMISNodeInfo cmisNodeInfo = cmisConnector.createNodeInfo(nodeRef); + cmisConnector.getContentStream(cmisNodeInfo, null, null, null); + return null; + }); + + RepoEvent downloadedRepoEvent = getRepoEvent(3); + assertEquals("Wrong repo event type.", EventType.NODE_DOWNLOADED.getType(), downloadedRepoEvent.getType()); + assertEquals("Downloaded event does not have the correct id", + getNodeResource(resultRepoEvent).getId(), + getNodeResource(downloadedRepoEvent).getId()); + assertNull("ResourceBefore field is not null", downloadedRepoEvent.getData().getResourceBefore()); + + retryingTransactionHelper.doInTransaction(() -> { + CMISNodeInfo cmisNodeInfo = cmisConnector.createNodeInfo(nodeRef); + cmisConnector.getContentStream(cmisNodeInfo, null, null, null); + return null; + }); + + // we should have 4 events: node.Created, node.Updated, node.Downloaded, node.Downloaded + checkNumOfEvents(4); + + downloadedRepoEvent = getRepoEvent(4); + assertEquals("Wrong repo event type.", EventType.NODE_DOWNLOADED.getType(), downloadedRepoEvent.getType()); + assertEquals("Downloaded event does not have the correct id", + getNodeResource(resultRepoEvent).getId(), + getNodeResource(downloadedRepoEvent).getId()); + assertNull("ResourceBefore field is not null", downloadedRepoEvent.getData().getResourceBefore()); + } +} diff --git a/src/test/java/org/alfresco/repo/event2/RepoEvent2ITSuite.java b/src/test/java/org/alfresco/repo/event2/RepoEvent2ITSuite.java index ff5a01bf6f..ca328b56b1 100644 --- a/src/test/java/org/alfresco/repo/event2/RepoEvent2ITSuite.java +++ b/src/test/java/org/alfresco/repo/event2/RepoEvent2ITSuite.java @@ -32,7 +32,8 @@ import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) @SuiteClasses({ org.alfresco.repo.event2.CreateRepoEventIT.class, org.alfresco.repo.event2.UpdateRepoEventIT.class, - org.alfresco.repo.event2.DeleteRepoEventIT.class }) + org.alfresco.repo.event2.DeleteRepoEventIT.class, + org.alfresco.repo.event2.DownloadRepoEventIT.class }) public class RepoEvent2ITSuite { }