From fd25e87fa4279f9b46e1158b0ade085ed2c810ba Mon Sep 17 00:00:00 2001 From: Harpritt Kalsi Date: Wed, 3 Oct 2012 11:11:25 +0000 Subject: [PATCH] Added test to reproduce bug described by ALF-14964. Queued Policies (TRANSACTION_COMMIT) are causing the Versionable aspect to be re-added after the rules have fired. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@42294 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repo/rule/RuleServiceIntegrationTest.java | 203 ++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 source/java/org/alfresco/repo/rule/RuleServiceIntegrationTest.java diff --git a/source/java/org/alfresco/repo/rule/RuleServiceIntegrationTest.java b/source/java/org/alfresco/repo/rule/RuleServiceIntegrationTest.java new file mode 100644 index 0000000000..6a6223deb9 --- /dev/null +++ b/source/java/org/alfresco/repo/rule/RuleServiceIntegrationTest.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * 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 . + */ + +package org.alfresco.repo.rule; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.util.Collections; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.action.executer.AddFeaturesActionExecuter; +import org.alfresco.repo.action.executer.RemoveFeaturesActionExecuter; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.model.Repository; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.action.ActionService; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.rule.RuleService; +import org.alfresco.service.cmr.rule.RuleType; +import org.alfresco.util.GUID; +import org.alfresco.util.test.junitrules.AlfrescoPerson; +import org.alfresco.util.test.junitrules.ApplicationContextInit; +import org.alfresco.util.test.junitrules.RunAsFullyAuthenticatedRule; +import org.alfresco.util.test.junitrules.TemporaryNodes; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; + +/** + * @author Harpritt Kalsi + * @since 3.4 + */ +public class RuleServiceIntegrationTest +{ + private static final String STANDARD_TEXT_CONTENT = "standardTextContent"; + + // Rule to initialise the default Alfresco spring configuration + public static ApplicationContextInit APP_CONTEXT_INIT = new ApplicationContextInit(); + + // Rules to create 2 test users. + public static AlfrescoPerson TEST_USER1 = new AlfrescoPerson(APP_CONTEXT_INIT, "UserOne"); + public static AlfrescoPerson TEST_USER2 = new AlfrescoPerson(APP_CONTEXT_INIT, "UserTwo"); + + // A rule to manage test nodes reused across all the test methods + public static TemporaryNodes STATIC_TEST_NODES = new TemporaryNodes(APP_CONTEXT_INIT); + + // Tie them together in a static Rule Chain + @ClassRule public static RuleChain ruleChain = RuleChain.outerRule(APP_CONTEXT_INIT) + .around(TEST_USER1) + .around(TEST_USER2) + .around(STATIC_TEST_NODES); + + // A rule to manage test nodes use in each test method + @Rule public TemporaryNodes testNodes = new TemporaryNodes(APP_CONTEXT_INIT); + + // A rule to allow individual test methods all to be run as "UserOne". + // Some test methods need to switch user during execution which they are free to do. + @Rule public RunAsFullyAuthenticatedRule runAsRule = new RunAsFullyAuthenticatedRule(TEST_USER1); + + // Various services + private static ServiceRegistry SERVICE_REGISTRY; + private static NodeService NODE_SERVICE; + private static RetryingTransactionHelper TRANSACTION_HELPER; + private static ActionService ACTION_SERVICE; + private static RuleService RULE_SERVICE; + private static ContentService CONTENT_SERVICE; + + + private static NodeRef COMPANY_HOME; + + // These NodeRefs are used by the test methods. + private static NodeRef TEST_FOLDER; + private NodeRef parentFolder; + private NodeRef childFolder; + private NodeRef childContent; + + + @BeforeClass public static void initStaticData() throws Exception + { + + SERVICE_REGISTRY = (ServiceRegistry)APP_CONTEXT_INIT.getApplicationContext().getBean(ServiceRegistry.SERVICE_REGISTRY); + NODE_SERVICE = SERVICE_REGISTRY.getNodeService(); + TRANSACTION_HELPER = SERVICE_REGISTRY.getRetryingTransactionHelper(); + ACTION_SERVICE = SERVICE_REGISTRY.getActionService(); + RULE_SERVICE = SERVICE_REGISTRY.getRuleService(); + CONTENT_SERVICE = SERVICE_REGISTRY.getContentService(); + + Repository repositoryHelper = (Repository) APP_CONTEXT_INIT.getApplicationContext().getBean("repositoryHelper"); + COMPANY_HOME = repositoryHelper.getCompanyHome(); + + // Create some static test content + TEST_FOLDER = STATIC_TEST_NODES.createNode(COMPANY_HOME, "testFolder", ContentModel.TYPE_FOLDER, AuthenticationUtil.getAdminUserName()); + + } + + @Before public void createTestContent() + { + parentFolder = testNodes.createNode(TEST_FOLDER, "testFolderInFolder", ContentModel.TYPE_FOLDER, TEST_USER2.getUsername()); + childFolder = testNodes.createNode(parentFolder, "testDocInFolder", ContentModel.TYPE_FOLDER, TEST_USER2.getUsername()); + childContent = testNodes.createNode(childFolder, "theTestContent", ContentModel.TYPE_CONTENT, TEST_USER2.getUsername()); + } + + + + @Ignore("Failing test, reproducing bug described by ALF-14964. " + + "Queued Policies (TRANSACTION_COMMIT) are causing the " + + "Versionable aspect to be re-added after the rules have fired.") + @Test public void testInheritedInvertedRule() throws Exception + { + TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + // We'll do all this as user 'UserTwo'. + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); + + //Parent Folder Rule: + //Add Versionable to newly created nodes + org.alfresco.service.cmr.rule.Rule parentRule = new org.alfresco.service.cmr.rule.Rule(); + parentRule.setRuleTypes(Collections.singletonList(RuleType.INBOUND)); + parentRule.setTitle("RuleServiceTest" + GUID.generate()); + parentRule.setDescription("Add Versionable"); + Action action = ACTION_SERVICE.createAction(AddFeaturesActionExecuter.NAME); + action.setParameterValue(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE); + parentRule.setAction(action); + parentRule.applyToChildren(true); + + //Child Folder Rule: + //Remove Versionable to newly created nodes + org.alfresco.service.cmr.rule.Rule childRule = new org.alfresco.service.cmr.rule.Rule(); + childRule.setRuleTypes(Collections.singletonList(RuleType.INBOUND)); + childRule.setTitle("RuleServiceTest" + GUID.generate()); + childRule.setDescription("RemoveVersonable"); + Action action2 = ACTION_SERVICE.createAction(RemoveFeaturesActionExecuter.NAME); + action2.setParameterValue(RemoveFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE); + childRule.setAction(action2); + childRule.applyToChildren(false); //Don't need to apply to children + + //Save Rules to appropriate Folders + RULE_SERVICE.saveRule(parentFolder, parentRule); + RULE_SERVICE.saveRule(childFolder, childRule); + return null; + } + }); + + //Trigger the inbound rules by adding content + addContentToNode(childContent); + + //Aspect is removed + assertTrue("Versionable Aspect was not removed", ! NODE_SERVICE.hasAspect(childContent, ContentModel.ASPECT_VERSIONABLE)); + + } + + + + @Test public void noOp() { /* Intentionally empty. */ } + + + + /** + * Adds content to a given node. + *

+ * Used to trigger rules of type of incomming. + * + * @param nodeRef the node reference + */ + private void addContentToNode(NodeRef nodeRef) + { + ContentWriter contentWriter = CONTENT_SERVICE.getWriter(nodeRef, ContentModel.PROP_CONTENT, true); + contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentWriter.setEncoding("UTF-8"); + assertNotNull(contentWriter); + contentWriter.putContent(STANDARD_TEXT_CONTENT + System.currentTimeMillis()); + } + +}