From 382a14adce28d3489436dc38c1dfc6ac7110da22 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Thu, 24 Mar 2016 18:30:52 +1100 Subject: [PATCH 1/6] Update release version to 2.2.1.5 --- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- rm-server/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index 058f832baf..b2574838d3 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -6,6 +6,6 @@ module.aliases=org_alfresco_module_dod5015 module.title=Records Management module.description=Alfresco Record Management Extension -module.version=2.2.1.4 +module.version=2.2.1.5 module.repo.version.min=4.2 \ No newline at end of file diff --git a/rm-server/pom.xml b/rm-server/pom.xml index afc57ed519..d25d5d2c59 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.2.1.4 + 2.2.1.5 4.0.0 alfresco-rm-server From a40aa2af338e73d98e2cf765e7b0ff2418fbe143 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 29 Mar 2016 13:09:56 +1100 Subject: [PATCH 2/6] RM-3114: Prevent access to custom map before it is ready - remove public init method from AdministrationService - make admin service impl ordered listener, always goes last - protect execution of service behaviours until custom map init'ed --- .gitignore | 1 + .../org_alfresco_module_rm/module-context.xml | 1 - .../rm-service-context.xml | 1 - .../admin/RecordsManagementAdminService.java | 5 - .../RecordsManagementAdminServiceImpl.java | 323 ++++++++++-------- .../bootstrap/RecordsManagementBootstrap.java | 12 +- 6 files changed, 185 insertions(+), 158 deletions(-) diff --git a/.gitignore b/.gitignore index 24be3fc3c1..4a0930f9db 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ test-output /rm-server/alfresco-solr.zip /rm-server/solr /rm-server/shared +/rm-server/alf_data # /rm-server/config/ /rm-server/config/alfresco-global.properties diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml index 1b1674c29f..4368604dde 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml @@ -168,7 +168,6 @@ - diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index 4057ea3e2d..54cd8dda2e 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -813,7 +813,6 @@ , + Ordered { /** Logger */ private static Log logger = LogFactory.getLog(RecordsManagementAdminServiceImpl.class); @@ -162,6 +167,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin /** List of types that can be customisable */ private List pendingCustomisableTypes; private Map customisableTypes; + + /** indicates whether the custom map has been initialised or not */ + private boolean isCustomMapInit = false; /** * @param dictionaryService the dictionary service @@ -223,15 +231,39 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin onCreateReferenceDelegate = policyComponent.registerClassPolicy(OnCreateReference.class); beforeRemoveReferenceDelegate = policyComponent.registerClassPolicy(BeforeRemoveReference.class); onRemoveReferenceDelegate = policyComponent.registerClassPolicy(OnRemoveReference.class); + } + + /** + * Indicate that this application content listener must be executed with the highest + * precedence. + * + * @see Ordered#getOrder() + */ + @Override + public int getOrder() + { + return Ordered.LOWEST_PRECEDENCE; + } + + /** + * Load the custom properties map + * + * @see ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) + */ + @Override + public void onApplicationEvent(ContextRefreshedEvent event) + { + // initialise custom properties + initCustomMap(); } /** - * Invoke before create reference policy - * - * @param fromNodeRef - * @param toNodeRef - * @param reference - */ + * Invoke before create reference policy + * + * @param fromNodeRef + * @param toNodeRef + * @param reference + */ protected void invokeBeforeCreateReference(NodeRef fromNodeRef, NodeRef toNodeRef, QName reference) { // get qnames to invoke against @@ -301,22 +333,25 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin ) public void onAddAspect(final NodeRef nodeRef, final QName aspectTypeQName) { - AuthenticationUtil.runAs(new RunAsWork() + if (isCustomMapInit) { - @Override - public Void doWork() + AuthenticationUtil.runAs(new RunAsWork() { - if (nodeService.exists(nodeRef) && - dictionaryService.getAllModels().contains(RM_CUSTOM_MODEL) && - isCustomisable(aspectTypeQName)) + @Override + public Void doWork() { - QName customPropertyAspect = getCustomAspect(aspectTypeQName); - nodeService.addAspect(nodeRef, customPropertyAspect, null); + if (nodeService.exists(nodeRef) && + dictionaryService.getAllModels().contains(RM_CUSTOM_MODEL) && + isCustomisable(aspectTypeQName)) + { + QName customPropertyAspect = getCustomAspect(aspectTypeQName); + nodeService.addAspect(nodeRef, customPropertyAspect, null); + } + + return null; } - - return null; - } - }, AuthenticationUtil.getSystemUserName()); + }, AuthenticationUtil.getSystemUserName()); + } } /** @@ -331,21 +366,24 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin ) public void onRemoveAspect(final NodeRef nodeRef, final QName aspectTypeQName) { - AuthenticationUtil.runAs(new RunAsWork() + if (isCustomMapInit) { - @Override - public Void doWork() + AuthenticationUtil.runAs(new RunAsWork() { - if (nodeService.exists(nodeRef) && - isCustomisable(aspectTypeQName)) + @Override + public Void doWork() { - QName customPropertyAspect = getCustomAspect(aspectTypeQName); - nodeService.removeAspect(nodeRef, customPropertyAspect); + if (nodeService.exists(nodeRef) && + isCustomisable(aspectTypeQName)) + { + QName customPropertyAspect = getCustomAspect(aspectTypeQName); + nodeService.removeAspect(nodeRef, customPropertyAspect); + } + + return null; } - - return null; - } - }, AuthenticationUtil.getSystemUserName()); + }, AuthenticationUtil.getSystemUserName()); + } } /** @@ -362,47 +400,41 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin ) public void onCreateNode(final ChildAssociationRef childAssocRef) { - AuthenticationUtil.runAs(new RunAsWork() - { - @Override - public Void doWork() + if (isCustomMapInit) + { + AuthenticationUtil.runAs(new RunAsWork() { - if (dictionaryService.getAllModels().contains(RecordsManagementCustomModel.RM_CUSTOM_MODEL)) + @Override + public Void doWork() { - NodeRef nodeRef = childAssocRef.getChildRef(); - QName type = nodeService.getType(nodeRef); - while (type != null && !ContentModel.TYPE_CMOBJECT.equals(type)) + if (dictionaryService.getAllModels().contains(RecordsManagementCustomModel.RM_CUSTOM_MODEL)) { - if (isCustomisable(type)) + NodeRef nodeRef = childAssocRef.getChildRef(); + QName type = nodeService.getType(nodeRef); + while (type != null && !ContentModel.TYPE_CMOBJECT.equals(type)) { - QName customPropertyAspect = getCustomAspect(type); - nodeService.addAspect(nodeRef, customPropertyAspect, null); - } - - TypeDefinition def = dictionaryService.getType(type); - if (def != null) - { - type = def.getParentName(); - } - else - { - type = null; + if (isCustomisable(type)) + { + QName customPropertyAspect = getCustomAspect(type); + nodeService.addAspect(nodeRef, customPropertyAspect, null); + } + + TypeDefinition def = dictionaryService.getType(type); + if (def != null) + { + type = def.getParentName(); + } + else + { + type = null; + } } } + + return null; } - - return null; - } - }, AuthenticationUtil.getSystemUserName()); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementAdminService#initialiseCustomModel() - */ - public void initialiseCustomModel() - { - // Initialise the map - getCustomisableMap(); + }, AuthenticationUtil.getSystemUserName()); + } } /** @@ -483,6 +515,92 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin return result; } + + /** + * Initialise custom type map + */ + private void initCustomMap() + { + customisableTypes = new HashMap(7); + Collection aspects = dictionaryService.getAspects(RM_CUSTOM_MODEL); + for (QName aspect : aspects) + { + AspectDefinition aspectDef = dictionaryService.getAspect(aspect); + String name = aspectDef.getName().getLocalName(); + if (name.endsWith("Properties")) + { + QName type = null; + String prefixString = aspectDef.getDescription(dictionaryService); + if (prefixString == null) + { + // Backward compatibility from previous RM V1.0 custom models + if (CompatibilityModel.NAME_CUSTOM_RECORD_PROPERTIES.equals(name)) + { + type = RecordsManagementModel.ASPECT_RECORD; + } + else if (CompatibilityModel.NAME_CUSTOM_RECORD_FOLDER_PROPERTIES.equals(name)) + { + type = RecordsManagementModel.TYPE_RECORD_FOLDER; + } + else if (CompatibilityModel.NAME_CUSTOM_RECORD_CATEGORY_PROPERTIES.equals(name)) + { + type = RecordsManagementModel.TYPE_RECORD_CATEGORY; + } + else if (CompatibilityModel.NAME_CUSTOM_RECORD_SERIES_PROPERTIES.equals(name) && + // Only add the deprecated record series type as customisable if + // a v1.0 installation has added custom properties + aspectDef.getProperties().size() != 0) + { + type = CompatibilityModel.TYPE_RECORD_SERIES; + } + } + else + { + type = QName.createQName(prefixString, namespaceService); + } + + // Add the customisable type to the map + if (type != null) + { + customisableTypes.put(type, aspect); + + // Remove customisable type from the pending list + if (pendingCustomisableTypes != null && pendingCustomisableTypes.contains(type)) + { + pendingCustomisableTypes.remove(type); + } + } + } + } + + // Deal with any pending types left over + if (pendingCustomisableTypes != null && pendingCustomisableTypes.size() != 0) + { + NodeRef modelRef = getCustomModelRef(RecordsManagementModel.RM_CUSTOM_URI); + M2Model model = readCustomContentModel(modelRef); + try + { + for (QName customisableType : pendingCustomisableTypes) + { + QName customAspect = getCustomAspectImpl(customisableType); + + // Create the new aspect to hold the custom properties + M2Aspect aspect = model.createAspect(customAspect.toPrefixString(namespaceService)); + aspect.setDescription(customisableType.toPrefixString(namespaceService)); + + // Make a record of the customisable type + customisableTypes.put(customisableType, customAspect); + } + } + finally + { + writeCustomContentModel(modelRef, model); + } + } + + // indicate map is initialised + isCustomMapInit = true; + } /** * Gets a map containing all the customisable types @@ -493,82 +611,7 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin { if (customisableTypes == null) { - customisableTypes = new HashMap(7); - Collection aspects = dictionaryService.getAspects(RM_CUSTOM_MODEL); - for (QName aspect : aspects) - { - AspectDefinition aspectDef = dictionaryService.getAspect(aspect); - String name = aspectDef.getName().getLocalName(); - if (name.endsWith("Properties")) - { - QName type = null; - String prefixString = aspectDef.getDescription(dictionaryService); - if (prefixString == null) - { - // Backward compatibility from previous RM V1.0 custom models - if (CompatibilityModel.NAME_CUSTOM_RECORD_PROPERTIES.equals(name)) - { - type = RecordsManagementModel.ASPECT_RECORD; - } - else if (CompatibilityModel.NAME_CUSTOM_RECORD_FOLDER_PROPERTIES.equals(name)) - { - type = RecordsManagementModel.TYPE_RECORD_FOLDER; - } - else if (CompatibilityModel.NAME_CUSTOM_RECORD_CATEGORY_PROPERTIES.equals(name)) - { - type = RecordsManagementModel.TYPE_RECORD_CATEGORY; - } - else if (CompatibilityModel.NAME_CUSTOM_RECORD_SERIES_PROPERTIES.equals(name) && - // Only add the deprecated record series type as customisable if - // a v1.0 installation has added custom properties - aspectDef.getProperties().size() != 0) - { - type = CompatibilityModel.TYPE_RECORD_SERIES; - } - } - else - { - type = QName.createQName(prefixString, namespaceService); - } - - // Add the customisable type to the map - if (type != null) - { - customisableTypes.put(type, aspect); - - // Remove customisable type from the pending list - if (pendingCustomisableTypes != null && pendingCustomisableTypes.contains(type)) - { - pendingCustomisableTypes.remove(type); - } - } - } - } - - // Deal with any pending types left over - if (pendingCustomisableTypes != null && pendingCustomisableTypes.size() != 0) - { - NodeRef modelRef = getCustomModelRef(RecordsManagementModel.RM_CUSTOM_URI); - M2Model model = readCustomContentModel(modelRef); - try - { - for (QName customisableType : pendingCustomisableTypes) - { - QName customAspect = getCustomAspectImpl(customisableType); - - // Create the new aspect to hold the custom properties - M2Aspect aspect = model.createAspect(customAspect.toPrefixString(namespaceService)); - aspect.setDescription(customisableType.toPrefixString(namespaceService)); - - // Make a record of the customisable type - customisableTypes.put(customisableType, customAspect); - } - } - finally - { - writeCustomContentModel(modelRef, model); - } - } + throw AlfrescoRuntimeException.create("Customisable map has not been initialised correctly."); } return customisableTypes; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java index 295059ead3..f681b9ef3a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java @@ -18,7 +18,6 @@ */ package org.alfresco.module.org_alfresco_module_rm.bootstrap; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; import org.alfresco.module.org_alfresco_module_rm.action.impl.SplitEmailAction; import org.alfresco.module.org_alfresco_module_rm.caveat.RMCaveatConfigService; import org.alfresco.module.org_alfresco_module_rm.email.CustomEmailMappingService; @@ -40,8 +39,7 @@ public class RecordsManagementBootstrap extends AbstractLifecycleBean private TransactionService transactionService; private RMCaveatConfigService caveatConfigService; private CustomEmailMappingService customEmailMappingService; - private RecordsManagementAdminService adminService; - + public void setTransactionService(TransactionService transactionService) { this.transactionService = transactionService; @@ -57,11 +55,6 @@ public class RecordsManagementBootstrap extends AbstractLifecycleBean this.customEmailMappingService = customEmailMappingService; } - public void setRecordsManagementAdminService(RecordsManagementAdminService adminService) - { - this.adminService = adminService; - } - public CustomEmailMappingService getCustomEmailMappingService() { return customEmailMappingService; @@ -82,9 +75,6 @@ public class RecordsManagementBootstrap extends AbstractLifecycleBean // initialise caveat config caveatConfigService.init(); - // Initialise the custom model - adminService.initialiseCustomModel(); - // Initialise the SplitEmailAction SplitEmailAction action = (SplitEmailAction)getApplicationContext().getBean("splitEmail"); action.bootstrap(); From bd39de53a1a12217a3c2996ef1ecd9d1ea16722e Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Wed, 30 Mar 2016 09:32:28 +1100 Subject: [PATCH 3/6] RM-3114 - Integration tests --- .../rm-service-context.xml | 1 + .../RecordsManagementAdminServiceImpl.java | 35 ++++- .../integration/issue/IssueTestSuite.java | 4 +- .../integration/issue/rm3314/RM3314Test.java | 52 +++++++ .../issue/rm3314/RM3314TestListener.java | 134 ++++++++++++++++++ rm-server/test/resources/test-context.xml | 17 +++ 6 files changed, 240 insertions(+), 3 deletions(-) create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index 54cd8dda2e..cc67b45a97 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -770,6 +770,7 @@ + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java index 79837871e2..66e1f803a0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java @@ -63,6 +63,7 @@ import org.alfresco.repo.policy.annotation.BehaviourBean; import org.alfresco.repo.policy.annotation.BehaviourKind; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.Constraint; @@ -83,6 +84,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.GUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -157,6 +159,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin /** Policy component */ private PolicyComponent policyComponent; + + /** Transaction service */ + private TransactionService transactionService; /** Policy delegates */ private ClassPolicyDelegate beforeCreateReferenceDelegate; @@ -220,6 +225,14 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin { this.dictonaryRepositoryBootstrap = dictonaryRepositoryBootstrap; } + + /** + * @param transactionService transaction service + */ + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } /** * Initialisation method @@ -253,8 +266,26 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin @Override public void onApplicationEvent(ContextRefreshedEvent event) { - // initialise custom properties - initCustomMap(); + transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + // initialise custom properties + initCustomMap(); + + return null; + } + }); + } + + /** + * Helper method to indicate whether the custom map is initialised or not. + * + * @return boolean true if initialised, false otherwise + */ + public boolean isCustomMapInit() + { + return isCustomMapInit; } /** diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java index 8c52e12ea1..2b86c45bf6 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java @@ -18,6 +18,7 @@ */ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; +import org.alfresco.module.org_alfresco_module_rm.test.integration.issue.rm3314.RM3314Test; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @@ -44,7 +45,8 @@ import org.junit.runners.Suite.SuiteClasses; RM1039Test.class, RM1799Test.class, //RM2190Test.class, - RM2192Test.class + RM2192Test.class, + RM3314Test.class }) public class IssueTestSuite { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java new file mode 100644 index 0000000000..89911e5fab --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.test.integration.issue.rm3314; + +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; + +/** + * Test for https://issues.alfresco.com/jira/browse/RM-3114 + * + * @author Roy Wetherall + * @since 2.2.1.5 + */ +public class RM3314Test extends BaseRMTestCase +{ + public static Map callback = new HashMap(2); + + /** + * Given that the custom model hasn't been initialised + * When an aspect is added + * Then nothing happens + * + * Given that the custom model has been initialised + * When an aspect is added + * Then something happens + */ + public void testListenersExecutedInTheCorrectOrder() + { + assertFalse(callback.isEmpty()); + assertFalse(callback.get("test.rm3314.1")); + assertTrue(callback.get("test.rm3314.2")); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java new file mode 100644 index 0000000000..d162d0fe95 --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314TestListener.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.test.integration.issue.rm3314; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminServiceImpl; +import org.alfresco.repo.model.Repository; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.Ordered; +import org.springframework.jdbc.BadSqlGrammarException; + +/** + * Simple bean used to test RM-3314 + * + * @author rwetherall + * @since 2.2.1.5 + */ +public class RM3314TestListener implements ApplicationListener, + Ordered, + BeanNameAware +{ + private RecordsManagementAdminServiceImpl recordsManagementAdminService; + private NodeService nodeService; + private FileFolderService fileFolderService; + private Repository repository; + + private String name; + private int order = Ordered.LOWEST_PRECEDENCE; + + public void setRecordsManagementAdminService(RecordsManagementAdminServiceImpl recordsManagementAdminService) + { + this.recordsManagementAdminService = recordsManagementAdminService; + } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setFileFolderService(FileFolderService fileFolderService) + { + this.fileFolderService = fileFolderService; + } + + public void setRepository(Repository repository) + { + this.repository = repository; + } + + @Override + public void setBeanName(String name) + { + this.name = name; + } + + public void setOrder(int order) + { + this.order = order; + } + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) + { + // call back to show whether the custom map is initialised or not + RM3314Test.callback.put(name, recordsManagementAdminService.isCustomMapInit()); + + // Do some work on a node to show that reguardless of whether the custom map is + // init or not, things still work. + // Note: using public services to ensure new transaction for each service call + AuthenticationUtil.runAsSystem(new RunAsWork() + { + public Void doWork() throws Exception + { + try + { + // create node + NodeRef folder = fileFolderService.create( + repository.getCompanyHome(), + name, + ContentModel.TYPE_FOLDER).getNodeRef(); + try + { + // add aspect + nodeService.addAspect(folder, ContentModel.ASPECT_CLASSIFIABLE, null); + + // remove aspect + nodeService.removeAspect(folder, ContentModel.ASPECT_CLASSIFIABLE); + } + finally + { + // delete node + nodeService.deleteNode(folder); + } + } + catch (BadSqlGrammarException e) + { + // ignore and carry on + } + + return null; + } + }); + } + + @Override + public int getOrder() + { + return order; + } +} diff --git a/rm-server/test/resources/test-context.xml b/rm-server/test/resources/test-context.xml index a5396c0b50..d0f608937c 100644 --- a/rm-server/test/resources/test-context.xml +++ b/rm-server/test/resources/test-context.xml @@ -240,4 +240,21 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file From 57e5d1d237d2619d30dc9aaebe24fa0783c7ec98 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 12 Apr 2016 09:21:45 -0400 Subject: [PATCH 4/6] RM-3114 - review comments --- .../admin/RecordsManagementAdminServiceImpl.java | 4 ++-- .../test/integration/issue/rm3314/RM3314Test.java | 11 ++++++++++- rm-server/test/resources/test-context.xml | 4 ++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java index 66e1f803a0..cc3f7d043b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java @@ -247,8 +247,8 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } /** - * Indicate that this application content listener must be executed with the highest - * precedence. + * Indicate that this application content listener must be executed with the lowest + * precedence. (ie last) * * @see Ordered#getOrder() */ diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java index 89911e5fab..7bc0a982bf 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/rm3314/RM3314Test.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2014 Alfresco Software Limited. + * Copyright (C) 2005-2016 Alfresco Software Limited. * * This file is part of Alfresco * @@ -32,6 +32,7 @@ import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; */ public class RM3314Test extends BaseRMTestCase { + /** registry to record callback from test beans "test.rm3114.1" and "test.rm3114.2" */ public static Map callback = new HashMap(2); /** @@ -45,6 +46,14 @@ public class RM3314Test extends BaseRMTestCase */ public void testListenersExecutedInTheCorrectOrder() { + /** + * The related test beans will call back into the callback map showing + * whether at the end of their execution whether the custom model has been + * initialised or not. Given the order in which these test beans are executed + * on spring context load, we would expect that .1 executes with the custom + * map unloaded, and the .2 with it loaded. + */ + assertFalse(callback.isEmpty()); assertFalse(callback.get("test.rm3314.1")); assertTrue(callback.get("test.rm3314.2")); diff --git a/rm-server/test/resources/test-context.xml b/rm-server/test/resources/test-context.xml index d0f608937c..6112260cb4 100644 --- a/rm-server/test/resources/test-context.xml +++ b/rm-server/test/resources/test-context.xml @@ -242,6 +242,8 @@ + @@ -250,6 +252,8 @@ + From 675b96ea73918cc7511aa5d0f32e7039226b1d93 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 12 Apr 2016 09:26:01 -0400 Subject: [PATCH 5/6] RM-3114 - update version in POMs --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b7ca9eae6f..a8a346f0db 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.2.1.4 + 2.2.1.5 Alfresco Records Management http://www.alfresco.org/ From 22d7efe18fee9ed0fa51e178680be116244f4de2 Mon Sep 17 00:00:00 2001 From: Roxana Lucanu Date: Mon, 16 May 2016 17:25:39 +0300 Subject: [PATCH 6/6] Updated version to 2.2.1.6-SNAPSHOT --- pom.xml | 2 +- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- rm-server/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a8a346f0db..39fdb13a41 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.2.1.5 + 2.2.1.6-SNAPSHOT Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index b2574838d3..427022be0f 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -6,6 +6,6 @@ module.aliases=org_alfresco_module_dod5015 module.title=Records Management module.description=Alfresco Record Management Extension -module.version=2.2.1.5 +module.version=2.2.1.6 module.repo.version.min=4.2 \ No newline at end of file diff --git a/rm-server/pom.xml b/rm-server/pom.xml index d25d5d2c59..f836866d99 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.2.1.5 + 2.2.1.6-SNAPSHOT 4.0.0 alfresco-rm-server