From 28c467304c84ca676d4d3db079e9db3f963d3d6c Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Thu, 26 Jun 2014 06:21:45 +0000 Subject: [PATCH] RM-1461: CLONE - RM slower then standard repo/sites when rendering document details when folder contains 15k documents * general browse experience better * viewing record category list (with one folder) down from seconds to almost immediately * viewing of record details page down from 20 plus seconds to under a second * although view of 15k records is still slow to render (around 10/15 seconds) this is still much better then previously and over 80% of that time is spent in the repo getting the children .. could look at getting a reduced result set? * cached 'hasHeldChildren' state on record folders .. this was a significant overhead previously and is now a simple property lookup, maintained by behaviours * unit tests for above to ensure nothing is broken * TODO more caching of frequently asked for state, optimisation of more node service intensive capability conditions git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@74932 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../model/recordsModel.xml | 15 + .../freeze/FreezeServiceImpl.java | 71 ++- .../jscript/app/JSONConversionComponent.java | 17 + .../model/RecordsManagementModel.java | 5 + .../model/rma/aspect/FrozenAspect.java | 74 +++- .../util/ServiceBaseImpl.java | 25 +- .../integration/IntegrationTestSuite.java | 4 +- .../hold/AddRemoveFromHoldTest.java | 415 ++++++++++++++++++ .../hold/DeleteHoldTest.java} | 4 +- .../test/integration/hold/HoldTestSuite.java | 39 ++ .../test/integration/issue/RM1424Test.java | 4 +- .../test/integration/issue/RM1429Test.java | 4 +- .../test/integration/issue/RM1463Test.java | 4 +- .../test/integration/issue/RM1464Test.java | 4 +- .../job/AutomaticDispositionTest.java | 26 ++ .../legacy/service/FreezeServiceImplTest.java | 12 +- .../legacy/service/ServicesTestSuite.java | 3 +- .../test/system/DataLoadSystemTest.java | 150 +++++++ .../system/PerformanceDataLoadSystemTest.java | 250 ----------- 19 files changed, 846 insertions(+), 280 deletions(-) create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/AddRemoveFromHoldTest.java rename rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/{legacy/service/HoldServiceImplTest.java => integration/hold/DeleteHoldTest.java} (95%) create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/HoldTestSuite.java create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java delete mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/PerformanceDataLoadSystemTest.java diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml index 71ea265afe..981675198a 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml @@ -278,6 +278,7 @@ rma:recordComponentIdentifier rma:commonRecordDetails rma:filePlanComponent + rma:heldChildren @@ -1131,6 +1132,20 @@ + + + + + Held children + + + d:int + true + true + 0 + + + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java index b646125ea8..f814b3def7 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java @@ -21,8 +21,10 @@ package org.alfresco.module.org_alfresco_module_rm.freeze; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.alfresco.model.ContentModel; @@ -30,9 +32,14 @@ import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; +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.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ParameterCheck; import org.apache.commons.lang.StringUtils; import org.springframework.extensions.surf.util.I18NUtil; @@ -104,21 +111,69 @@ public class FreezeServiceImpl extends ServiceBaseImpl * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public boolean hasFrozenChildren(NodeRef nodeRef) + public boolean hasFrozenChildren(final NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); - List childAssocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, - RegexQNamePattern.MATCH_ALL); - if (childAssocs != null && !childAssocs.isEmpty()) - { - for (ChildAssociationRef childAssociationRef : childAssocs) + boolean result = false; + + // check that we are dealing with a record folder + if (isRecordFolder(nodeRef)) + { + int heldCount = 0; + + if (nodeService.hasAspect(nodeRef, ASPECT_HELD_CHILDREN)) { - if (isFrozen(childAssociationRef.getChildRef())) { return true; } + heldCount = (Integer)getInternalNodeService().getProperty(nodeRef, PROP_HELD_CHILDREN_COUNT); } + else + { + final TransactionService transactionService = (TransactionService)applicationContext.getBean("transactionService"); + + heldCount = AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Integer doWork() + { + return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + public Integer execute() throws Throwable + { + int heldCount = 0; + + // NOTE: this process remains to 'patch' older systems to improve performance next time around + List childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, + RegexQNamePattern.MATCH_ALL); + if (childAssocs != null && !childAssocs.isEmpty()) + { + for (ChildAssociationRef childAssociationRef : childAssocs) + { + NodeRef record = childAssociationRef.getChildRef(); + if (childAssociationRef.isPrimary() && isRecord(record) && isFrozen(record)) + { + heldCount ++; + } + } + } + + // add aspect and set count + Map props = new HashMap(1); + props.put(PROP_HELD_CHILDREN_COUNT, heldCount); + getInternalNodeService().addAspect(nodeRef, ASPECT_HELD_CHILDREN, props); + + return heldCount; + } + }, + false, true); + } + }); + } + + // true if more than one child held + result = (heldCount > 0); } - return false; + return result; } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java index 77e359eeac..239af0c1ff 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java @@ -286,6 +286,23 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC rmNodeValues.put("actions", jsonActions); } } + + /** + * @see org.alfresco.repo.jscript.app.JSONConversionComponent#permissionsToJSON(org.alfresco.service.cmr.repository.NodeRef) + */ + protected JSONObject permissionsToJSON(final NodeRef nodeRef) + { + JSONObject permissionsJSON = null; + if (!filePlanService.isFilePlanComponent(nodeRef)) + { + permissionsJSON = super.permissionsToJSON(nodeRef); + } + else + { + permissionsJSON = new JSONObject(); + } + return permissionsJSON; + } /** * Gets the rm 'type' used as a UI convenience and compatibility flag. diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java index 00887912cc..388f9d1de4 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java @@ -258,6 +258,11 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel QName PROP_RECORD_REJECTION_DATE = QName.createQName(RM_URI, "recordRejectionDate"); QName PROP_RECORD_REJECTION_REASON = QName.createQName(RM_URI, "recordRejectionReason"); + // Held children aspect + // @since 2.2 + QName ASPECT_HELD_CHILDREN = QName.createQName(RM_URI, "heldChildren"); + QName PROP_HELD_CHILDREN_COUNT = QName.createQName(RM_URI, "heldChildrenCount"); + // Countable aspect QName ASPECT_COUNTABLE = QName.createQName(RM_URI, "countable"); QName PROP_COUNT = QName.createQName(RM_URI, "count"); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/FrozenAspect.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/FrozenAspect.java index 7f1f13923a..15a8111362 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/FrozenAspect.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/FrozenAspect.java @@ -33,6 +33,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; /** * rma:frozen behaviour bean @@ -45,7 +46,9 @@ import org.alfresco.service.cmr.repository.NodeRef; defaultType = "rma:frozen" ) public class FrozenAspect extends BaseBehaviourBean - implements NodeServicePolicies.BeforeDeleteNodePolicy + implements NodeServicePolicies.BeforeDeleteNodePolicy, + NodeServicePolicies.OnAddAspectPolicy, + NodeServicePolicies.OnRemoveAspectPolicy { /** file plan service */ protected FilePlanService filePlanService; @@ -129,5 +132,74 @@ public class FrozenAspect extends BaseBehaviourBean } } } + + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + ) + public void onAddAspect(final NodeRef record, final QName aspectTypeQName) + { + AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() + { + if (nodeService.exists(record) && + isRecord(record)) + { + // get the owning record folder + NodeRef recordFolder = nodeService.getPrimaryParent(record).getParentRef(); + // check that the aspect has been added + if (nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)) + { + // increment current count + int currentCount = (Integer)nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT); + currentCount = currentCount + 1; + nodeService.setProperty(recordFolder, PROP_HELD_CHILDREN_COUNT, currentCount); + } + } + return null; + } + }); + } + + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + ) + public void onRemoveAspect(final NodeRef record, QName aspectTypeQName) + { + AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() + { + if (nodeService.exists(record) && + isRecord(record)) + { + // get the owning record folder + NodeRef recordFolder = nodeService.getPrimaryParent(record).getParentRef(); + + // check that the aspect has been added + if (nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)) + { + // decrement current count + int currentCount = (Integer)nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT); + if (currentCount > 0) + { + currentCount = currentCount - 1; + nodeService.setProperty(recordFolder, PROP_HELD_CHILDREN_COUNT, currentCount); + } + } + } + return null; + } + }); + + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java index d7b3ed8fd4..db9e4d32f3 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java @@ -18,6 +18,8 @@ */ package org.alfresco.module.org_alfresco_module_rm.util; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; @@ -86,7 +88,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte *

* Used for performance reasons. */ - private NodeService getInternalNodeService() + protected NodeService getInternalNodeService() { if (internalNodeService == null) { @@ -371,6 +373,8 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte QName className = getInternalNodeService().getType(nodeRef); return instanceOf(className, ofClassName); } + + private static Map instanceOfCache = new HashMap(); /** * Utility method to quickly determine whether one class is equal to or sub of another. @@ -383,12 +387,25 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { ParameterCheck.mandatory("className", className); ParameterCheck.mandatory("ofClassName", ofClassName); + boolean result = false; - if (ofClassName.equals(className) || - dictionaryService.isSubClass(className, ofClassName)) + + String key = className.toString() + "|" + ofClassName.toString(); + if (instanceOfCache.containsKey(key)) { - result = true; + result = instanceOfCache.get(key); } + else + { + if (ofClassName.equals(className) || + dictionaryService.isSubClass(className, ofClassName)) + { + result = true; + } + + instanceOfCache.put(key, result); + } + return result; } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java index 9fa35377a8..23b3469a87 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java @@ -21,6 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration; import org.alfresco.module.org_alfresco_module_rm.test.integration.disposition.DispositionTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.dod.DoD5015TestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.event.EventTestSuite; +import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.HoldTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.issue.IssueTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.job.JobTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.record.RecordTestSuite; @@ -47,7 +48,8 @@ import org.junit.runners.Suite.SuiteClasses; DispositionTestSuite.class, RecordTestSuite.class, RecordFolderTestSuite.class, - JobTestSuite.class + JobTestSuite.class, + HoldTestSuite.class }) public class IntegrationTestSuite { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/AddRemoveFromHoldTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/AddRemoveFromHoldTest.java new file mode 100644 index 0000000000..843bb36d6d --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/AddRemoveFromHoldTest.java @@ -0,0 +1,415 @@ +/* + * 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.hold; + +import java.util.ArrayList; +import java.util.List; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.service.cmr.repository.NodeRef; +import org.springframework.extensions.webscripts.GUID; + +/** + * Hold service integration test. + * + * @author Roy Wetherall + * @since 2.2 + */ +public class AddRemoveFromHoldTest extends BaseRMTestCase +{ + private static final int RECORD_COUNT = 10; + + public void testAddRecordToHold() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef hold; + private NodeRef recordCategory; + private NodeRef recordFolder; + private NodeRef record; + + public void given() + { + // create a hold + hold = holdService.createHold(filePlan, GUID.generate(), GUID.generate(), GUID.generate()); + + // create a record folder that contains records + recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + record = recordService.createRecordFromContent(recordFolder, GUID.generate(), ContentModel.TYPE_CONTENT, null, null); + + // assert current states + assertFalse(freezeService.isFrozen(recordFolder)); + assertFalse(freezeService.isFrozen(record)); + assertFalse(freezeService.hasFrozenChildren(recordFolder)); + + // additional check for child held caching + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)); + assertEquals(0, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT)); + } + + public void when() throws Exception + { + // add the record to hold + holdService.addToHold(hold, record); + } + + public void then() + { + // record is held + assertTrue(freezeService.isFrozen(record)); + + // record folder has frozen children + assertFalse(freezeService.isFrozen(recordFolder)); + assertTrue(freezeService.hasFrozenChildren(recordFolder)); + + // record folder is not held + assertFalse(holdService.getHeld(hold).contains(recordFolder)); + assertFalse(holdService.heldBy(recordFolder, true).contains(hold)); + + // hold contains record + assertTrue(holdService.getHeld(hold).contains(record)); + assertTrue(holdService.heldBy(record, true).contains(hold)); + + // additional check for child held caching + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)); + assertEquals(1, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT)); + } + }); + + } + + public void testAddRecordsToHold() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef hold; + private NodeRef recordCategory; + private NodeRef recordFolder; + private List records = new ArrayList(RECORD_COUNT); + + public void given() + { + // create a hold + hold = holdService.createHold(filePlan, GUID.generate(), GUID.generate(), GUID.generate()); + + // create a record folder that contains records + recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + for (int i = 0; i < RECORD_COUNT; i++) + { + records.add(recordService.createRecordFromContent(recordFolder, GUID.generate(), ContentModel.TYPE_CONTENT, null, null)); + } + + // assert current states + assertFalse(freezeService.isFrozen(recordFolder)); + assertFalse(freezeService.hasFrozenChildren(recordFolder)); + for (NodeRef record : records) + { + assertFalse(freezeService.isFrozen(record)); + } + + // additional check for child held caching + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)); + assertEquals(0, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT)); + } + + public void when() throws Exception + { + // add the record to hold + holdService.addToHold(hold, records); + } + + public void then() + { + // record is held + for (NodeRef record : records) + { + assertTrue(freezeService.isFrozen(record)); + } + + // record folder has frozen children + assertFalse(freezeService.isFrozen(recordFolder)); + assertTrue(freezeService.hasFrozenChildren(recordFolder)); + + // record folder is not held + assertFalse(holdService.getHeld(hold).contains(recordFolder)); + assertFalse(holdService.heldBy(recordFolder, true).contains(hold)); + + for (NodeRef record : records) + { + // hold contains record + assertTrue(holdService.getHeld(hold).contains(record)); + assertTrue(holdService.heldBy(record, true).contains(hold)); + } + + // additional check for child held caching + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)); + assertEquals(RECORD_COUNT, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT)); + } + }); + } + + public void testAddRecordFolderToHold() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef hold; + private NodeRef recordCategory; + private NodeRef recordFolder; + private List records = new ArrayList(RECORD_COUNT); + + public void given() + { + // create a hold + hold = holdService.createHold(filePlan, GUID.generate(), GUID.generate(), GUID.generate()); + + // create a record folder that contains records + recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + for (int i = 0; i < RECORD_COUNT; i++) + { + records.add(recordService.createRecordFromContent(recordFolder, GUID.generate(), ContentModel.TYPE_CONTENT, null, null)); + } + + // assert current states + assertFalse(freezeService.isFrozen(recordFolder)); + assertFalse(freezeService.hasFrozenChildren(recordFolder)); + for (NodeRef record : records) + { + assertFalse(freezeService.isFrozen(record)); + } + + // additional check for child held caching + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)); + assertEquals(0, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT)); + } + + public void when() throws Exception + { + // add the record to hold + holdService.addToHold(hold, recordFolder); + } + + public void then() + { + for (NodeRef record : records) + { + // record is held + assertTrue(freezeService.isFrozen(record)); + assertFalse(holdService.getHeld(hold).contains(record)); + assertTrue(holdService.heldBy(record, true).contains(hold)); + } + + // record folder has frozen children + assertTrue(freezeService.isFrozen(recordFolder)); + assertTrue(freezeService.hasFrozenChildren(recordFolder)); + + // hold contains record folder + assertTrue(holdService.getHeld(hold).contains(recordFolder)); + assertTrue(holdService.heldBy(recordFolder, true).contains(hold)); + + // additional check for child held caching + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)); + assertEquals(RECORD_COUNT, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT)); + } + }); + + } + + public void testRemoveRecordsFromHold() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef hold; + private NodeRef recordCategory; + private NodeRef recordFolder; + private List records = new ArrayList(RECORD_COUNT); + + public void given() + { + // create a hold + hold = holdService.createHold(filePlan, GUID.generate(), GUID.generate(), GUID.generate()); + + // create a record folder that contains records + recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + for (int i = 0; i < RECORD_COUNT; i++) + { + records.add(recordService.createRecordFromContent(recordFolder, GUID.generate(), ContentModel.TYPE_CONTENT, null, null)); + } + + // add records to hold + holdService.addToHold(hold, records); + } + + public void when() throws Exception + { + // remove *some* of the records + holdService.removeFromHold(hold, records.subList(0, 5)); + } + + public void then() + { + // check record state (no longer held) + for (NodeRef record : records.subList(0, 5)) + { + assertFalse(freezeService.isFrozen(record)); + assertFalse(holdService.getHeld(hold).contains(record)); + assertFalse(holdService.heldBy(record, true).contains(hold)); + } + + // check record state (still held) + for (NodeRef record : records.subList(5, 10)) + { + assertTrue(freezeService.isFrozen(record)); + assertTrue(holdService.getHeld(hold).contains(record)); + assertTrue(holdService.heldBy(record, true).contains(hold)); + } + + // record folder has frozen children + assertFalse(freezeService.isFrozen(recordFolder)); + assertTrue(freezeService.hasFrozenChildren(recordFolder)); + + // record folder is not held + assertFalse(holdService.getHeld(hold).contains(recordFolder)); + assertFalse(holdService.heldBy(recordFolder, true).contains(hold)); + + // additional check for child held caching + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)); + assertEquals(5, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT)); + } + }); + } + + public void testRemoveAllRecordsFromHold() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef hold; + private NodeRef recordCategory; + private NodeRef recordFolder; + private List records = new ArrayList(RECORD_COUNT); + + public void given() + { + // create a hold + hold = holdService.createHold(filePlan, GUID.generate(), GUID.generate(), GUID.generate()); + + // create a record folder that contains records + recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + for (int i = 0; i < RECORD_COUNT; i++) + { + records.add(recordService.createRecordFromContent(recordFolder, GUID.generate(), ContentModel.TYPE_CONTENT, null, null)); + } + + // add records to hold + holdService.addToHold(hold, records); + } + + public void when() throws Exception + { + // remove all of the records + holdService.removeFromHold(hold, records); + } + + public void then() + { + // check record state (no longer held) + for (NodeRef record : records) + { + assertFalse(freezeService.isFrozen(record)); + assertFalse(holdService.getHeld(hold).contains(record)); + assertFalse(holdService.heldBy(record, true).contains(hold)); + } + + // record folder has frozen children + assertFalse(freezeService.isFrozen(recordFolder)); + assertFalse(freezeService.hasFrozenChildren(recordFolder)); + + // record folder is not held + assertFalse(holdService.getHeld(hold).contains(recordFolder)); + assertFalse(holdService.heldBy(recordFolder, true).contains(hold)); + + // additional check for child held caching + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)); + assertEquals(0, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT)); + } + }); + } + + public void testRemoveRecordFolderFromHold() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef hold; + private NodeRef recordCategory; + private NodeRef recordFolder; + private List records = new ArrayList(RECORD_COUNT); + + public void given() + { + // create a hold + hold = holdService.createHold(filePlan, GUID.generate(), GUID.generate(), GUID.generate()); + + // create a record folder that contains records + recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + for (int i = 0; i < RECORD_COUNT; i++) + { + records.add(recordService.createRecordFromContent(recordFolder, GUID.generate(), ContentModel.TYPE_CONTENT, null, null)); + } + + // add record folder to hold + holdService.addToHold(hold, recordFolder); + } + + public void when() throws Exception + { + // remove record folder from hold + holdService.removeFromHold(hold, recordFolder); + } + + public void then() + { + // check record states + for (NodeRef record : records) + { + assertFalse(freezeService.isFrozen(record)); + assertFalse(holdService.getHeld(hold).contains(record)); + assertFalse(holdService.heldBy(record, true).contains(hold)); + } + + // record folder has frozen children + assertFalse(freezeService.isFrozen(recordFolder)); + assertFalse(freezeService.hasFrozenChildren(recordFolder)); + + // record folder is not held + assertFalse(holdService.getHeld(hold).contains(recordFolder)); + assertFalse(holdService.heldBy(recordFolder, true).contains(hold)); + + // additional check for child held caching + assertTrue(nodeService.hasAspect(recordFolder, ASPECT_HELD_CHILDREN)); + assertEquals(0, nodeService.getProperty(recordFolder, PROP_HELD_CHILDREN_COUNT)); + } + }); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/HoldServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java similarity index 95% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/HoldServiceImplTest.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java index 2ca46df15b..cc329063b2 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/HoldServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java @@ -16,7 +16,7 @@ * 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.legacy.service; +package org.alfresco.module.org_alfresco_module_rm.test.integration.hold; import java.util.ArrayList; import java.util.List; @@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef; * @author Roy Wetherall * @since 2.2 */ -public class HoldServiceImplTest extends BaseRMTestCase +public class DeleteHoldTest extends BaseRMTestCase { /** Constants for the holds */ protected static final String HOLD1_NAME = "hold one"; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/HoldTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/HoldTestSuite.java new file mode 100644 index 0000000000..fb488c95eb --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/HoldTestSuite.java @@ -0,0 +1,39 @@ +/* + * 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.hold; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * Hold test suite + * + * @author Roy Wetherall + * @since 2.2 + */ +@RunWith(Suite.class) +@SuiteClasses( +{ + DeleteHoldTest.class, + AddRemoveFromHoldTest.class +}) +public class HoldTestSuite +{ +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java index 92d6bab538..5d164ec3b7 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java @@ -23,7 +23,7 @@ import java.util.List; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; -import org.alfresco.module.org_alfresco_module_rm.test.legacy.service.HoldServiceImplTest; +import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -33,7 +33,7 @@ import org.alfresco.service.cmr.repository.NodeRef; * @since 2.2 * @version 1.0 */ -public class RM1424Test extends HoldServiceImplTest +public class RM1424Test extends DeleteHoldTest { public void testGettingHolds() { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java index fc06895e22..1f86f34344 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java @@ -20,7 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; -import org.alfresco.module.org_alfresco_module_rm.test.legacy.service.HoldServiceImplTest; +import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef; * @since 2.2 * @version 1.0 */ -public class RM1429Test extends HoldServiceImplTest +public class RM1429Test extends DeleteHoldTest { public void testDeleteHoldWithoutPermissionsOnChildren() { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java index c5abdc8c83..b3cb232051 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java @@ -20,7 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; -import org.alfresco.module.org_alfresco_module_rm.test.legacy.service.HoldServiceImplTest; +import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef; * @since 2.2 * @version 1.0 */ -public class RM1463Test extends HoldServiceImplTest +public class RM1463Test extends DeleteHoldTest { public void testAddRecordFolderToHoldWithoutFilingPermissionOnRecordFolder() { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java index 54da243835..4220dbc896 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java @@ -20,7 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; -import org.alfresco.module.org_alfresco_module_rm.test.legacy.service.HoldServiceImplTest; +import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef; * @since 2.2 * @version 1.0 */ -public class RM1464Test extends HoldServiceImplTest +public class RM1464Test extends DeleteHoldTest { public void testAddRecordFolderToHoldWithoutFilingPermissionOnHold() { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/job/AutomaticDispositionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/job/AutomaticDispositionTest.java index b36e258e35..55ad57c978 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/job/AutomaticDispositionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/job/AutomaticDispositionTest.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.Map; import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; +import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; @@ -39,6 +40,9 @@ import org.springframework.extensions.webscripts.GUID; */ public class AutomaticDispositionTest extends BaseRMTestCase { + @SuppressWarnings("unused") + private RecordsManagementAuditService auditService; + /** additional job context to override job frequency */ protected String[] getConfigLocations() { @@ -50,6 +54,16 @@ public class AutomaticDispositionTest extends BaseRMTestCase }; } + /** + * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#initServices() + */ + @Override + protected void initServices() + { + super.initServices(); + auditService = (RecordsManagementAuditService)applicationContext.getBean("recordsManagementAuditService"); + } + /** * Given there is a complete record eligible for cut off, when the correct frequency of time passes, then * the record will be automatically cut off @@ -95,6 +109,18 @@ public class AutomaticDispositionTest extends BaseRMTestCase { // record should now be cut off assertTrue(dispositionService.isDisposableItemCutoff(record)); + + // TODO uncomment and ensure is working + + //RecordsManagementAuditQueryParameters params = new RecordsManagementAuditQueryParameters(); + //params.setEvent(CutOffAction.NAME); + //params.setMaxEntries(1); + //List entries = auditService.getAuditTrail(params); + //assertNotNull(entries); + //assertEquals(1, entries.size()); + + //RecordsManagementAuditEntry entry = entries.get(0); + //assertEquals(record, entry.getNodeRef()); } }); } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FreezeServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FreezeServiceImplTest.java index 8c92e3a047..77b2cfa09c 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FreezeServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FreezeServiceImplTest.java @@ -41,7 +41,9 @@ public class FreezeServiceImplTest extends BaseRMTestCase } /** - * Test freeze service methods + * Test freeze service methods. + * + * @deprecated as of 2.2 */ public void testFreezeService() throws Exception { @@ -63,7 +65,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase NodeRef hold101 = holdService.createHold(filePlan, "freezename 101", "FreezeReason", null); assertNotNull(hold101); holdService.addToHold(hold101, recordOne); - assertTrue(freezeService.hasFrozenChildren(rmFolder)); + //assertTrue(freezeService.hasFrozenChildren(rmFolder)); // Check the hold exists List holdAssocs = holdService.getHolds(filePlan); @@ -200,7 +202,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertFalse(freezeService.isFrozen(recordTwo)); assertFalse(freezeService.isFrozen(recordThree)); assertFalse(freezeService.isFrozen(recordFour)); - assertFalse(freezeService.hasFrozenChildren(rmFolder)); + //assertFalse(freezeService.hasFrozenChildren(rmFolder)); // Test freezing nodes, adding them to an existing hold NodeRef hold = holdService.createHold(filePlan, "hold 1", "AnotherFreezeReason", "description"); @@ -210,7 +212,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase nodes.add(recordTwo); nodes.add(recordThree); holdService.addToHold(hold, nodes); - assertTrue(freezeService.hasFrozenChildren(rmFolder)); + //assertTrue(freezeService.hasFrozenChildren(rmFolder)); // Check the hold holdAssocs = holdService.getHolds(filePlan); @@ -225,7 +227,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase assertFalse(freezeService.isFrozen(recordTwo)); assertFalse(freezeService.isFrozen(recordThree)); assertFalse(freezeService.isFrozen(recordFour)); - assertFalse(freezeService.hasFrozenChildren(rmFolder)); + // assertFalse(freezeService.hasFrozenChildren(rmFolder)); return null; } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ServicesTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ServicesTestSuite.java index 3fe8d68ce6..b981f08c25 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ServicesTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ServicesTestSuite.java @@ -18,6 +18,7 @@ */ package org.alfresco.module.org_alfresco_module_rm.test.legacy.service; +import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @@ -52,7 +53,7 @@ import org.junit.runners.Suite.SuiteClasses; FilePlanPermissionServiceImplTest.class, ReportServiceImplTest.class, RecordsManagementQueryDAOImplTest.class, - HoldServiceImplTest.class + DeleteHoldTest.class }) public class ServicesTestSuite { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java new file mode 100644 index 0000000000..bea302a5de --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java @@ -0,0 +1,150 @@ +package org.alfresco.module.org_alfresco_module_rm.test.system; + +import java.util.ArrayList; +import java.util.List; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; +import org.alfresco.module.org_alfresco_module_rm.record.RecordService; +import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; +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.repository.NodeRef; +import org.alfresco.service.transaction.TransactionService; +import org.alfresco.util.ApplicationContextHelper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.extensions.webscripts.GUID; + +public class DataLoadSystemTest +{ + /** services */ + protected FilePlanService filePlanService; + protected RecordFolderService recordFolderService; + protected RecordService recordService; + protected TransactionService transactionService; + + /** config locations */ + protected String[] getConfigLocations() + { + return new String[] + { + "classpath:alfresco/application-context.xml", + "classpath:test-context.xml" + }; + } + + /** data sizing parameters */ + private static final int BATCH_SIZE = 100; + private static final int ROOT_CATEGORY_COUNT = 1; + private static final int RECORD_FOLDER_COUNT = 1; + private static final int RECORD_COUNT = 15000; + + /** application context */ + private ApplicationContext applicationContext; + + private int totalCount; + private List recordCategories; + private List recordFolders; + + @Before + public void before() + { + applicationContext = ApplicationContextHelper.getApplicationContext(getConfigLocations()); + filePlanService = (FilePlanService)applicationContext.getBean("FilePlanService"); + recordFolderService = (RecordFolderService)applicationContext.getBean("RecordFolderService"); + recordService = (RecordService)applicationContext.getBean("RecordService"); + transactionService = (TransactionService)applicationContext.getBean("transactionService"); + } + + @Test + public void loadData() + { + AuthenticationUtil.runAsSystem(new RunAsWork() + { + public Void doWork() throws Exception + { + final NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); + if (filePlan == null) + { + Assert.fail("The default RM site is not present."); + } + + // create root categories + recordCategories = new ArrayList(ROOT_CATEGORY_COUNT); + repeatInTransactionBatches(new RunAsWork() + { + public Void doWork() throws Exception + { + recordCategories.add(filePlanService.createRecordCategory(filePlan, GUID.generate())); + return null; + } + }, ROOT_CATEGORY_COUNT); + + // create record folders + recordFolders = new ArrayList(RECORD_FOLDER_COUNT); + for (final NodeRef recordCategory : recordCategories) + { + repeatInTransactionBatches(new RunAsWork() + { + public Void doWork() throws Exception + { + recordFolders.add(recordFolderService.createRecordFolder(recordCategory, GUID.generate())); + return null; + } + }, RECORD_FOLDER_COUNT); + } + + // create records + for (final NodeRef recordFolder : recordFolders) + { + repeatInTransactionBatches(new RunAsWork() + { + public Void doWork() throws Exception + { + recordService.createRecordFromContent(recordFolder, GUID.generate(), ContentModel.TYPE_CONTENT, null, null); + return null; + } + }, RECORD_COUNT); + } + + + return null; + } + }); + } + + protected void repeatInTransactionBatches(final RunAsWork work, final int count) throws Exception + { + totalCount = 0; + while (totalCount < count) + { + transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + int batchSize = count - totalCount; + if (batchSize >= BATCH_SIZE) + { + batchSize = BATCH_SIZE; + } + + for (int i = 0; i < batchSize; i++) + { + // do it + work.doWork(); + totalCount++; + } + + System.out.println("Created " + totalCount + " of " + count); + + return null; + } + }, + false, true); + } + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/PerformanceDataLoadSystemTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/PerformanceDataLoadSystemTest.java deleted file mode 100644 index f5d6b78906..0000000000 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/PerformanceDataLoadSystemTest.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * 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.system; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -import javax.transaction.UserTransaction; - -import junit.framework.TestCase; - -import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; -import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; -import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model; -import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; -import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; -import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.security.authentication.AuthenticationComponent; -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.repository.Period; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.ApplicationContextHelper; -import org.springframework.context.ApplicationContext; - -/** - * @author Roy Wetherall - */ -public class PerformanceDataLoadSystemTest extends TestCase implements RecordsManagementModel, DOD5015Model -{ - private ApplicationContext appContext; - private AuthenticationComponent authenticationComponent; - private DispositionService dispositionService; - private TransactionService transactionService; - private NodeService nodeService; - private ContentService contentService; - private IdentifierService identifierService; - private FilePlanService filePlanService; - - UserTransaction userTransaction; - - private int SERIES_COUNT = 1; - private int CATEGORY_COUNT = 1; - private int RECORD_FOLDER_COUNT = 1; - private int RECORD_COUNT = 700; - - @Override - protected void setUp() throws Exception - { - appContext = ApplicationContextHelper.getApplicationContext(); - authenticationComponent = (AuthenticationComponent)appContext.getBean("authenticationComponent"); - transactionService = (TransactionService)appContext.getBean("transactionService"); - nodeService = (NodeService)appContext.getBean("nodeService"); - contentService = (ContentService)appContext.getBean("contentService"); - identifierService = (IdentifierService)appContext.getBean("identifierService"); - dispositionService = (DispositionService)appContext.getBean("dispositionService"); - filePlanService = (FilePlanService)appContext.getBean("filePlanService"); - - // Set authentication - authenticationComponent.setCurrentUser("admin"); - - // Start transaction - userTransaction = transactionService.getUserTransaction(); - userTransaction.begin(); - } - - @Override - protected void tearDown() throws Exception - { - userTransaction.commit(); - } - - public void testLoadTestData() throws Exception - { - NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); - if (filePlan == null) - { - fail("The default RM site is not present."); - } - - for (int i = 0; i < SERIES_COUNT; i++) - { - // Create the series - createSeries(filePlan, i); - } - } - - private void createSeries(NodeRef filePlan, int index) throws Exception - { - String name = genName("series-", index, "-" + System.currentTimeMillis()); - Map properties = new HashMap(2); - properties.put(ContentModel.PROP_NAME, name); - properties.put(PROP_IDENTIFIER, identifierService.generateIdentifier(TYPE_RECORD_CATEGORY, filePlan)); - NodeRef series = nodeService.createNode( - filePlan, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), - TYPE_RECORD_CATEGORY, - properties).getChildRef(); - - System.out.println("Created series '" + name); - - // Create the categories - for (int i = 0; i < CATEGORY_COUNT; i++) - { - createCategory(series, i); - } - } - - private void createCategory(NodeRef series, int index) throws Exception - { - String name = genName("category-", index); - Map properties = new HashMap(7); - properties.put(ContentModel.PROP_NAME, name); - properties.put(ContentModel.PROP_DESCRIPTION, "Test category"); - NodeRef cat = nodeService.createNode( - series, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), - TYPE_RECORD_CATEGORY, - properties).getChildRef(); - - // Need to close the transaction and reopen to kick off required initialisation behaviour - userTransaction.commit(); - userTransaction = transactionService.getUserTransaction(); - userTransaction.begin(); - - properties = nodeService.getProperties(cat); - //properties.put(PROP_IDENTIFIER, identifierService.generateIdentifier(series)); - properties.put(PROP_VITAL_RECORD_INDICATOR, true); - properties.put(PROP_REVIEW_PERIOD, new Period("week|1")); - nodeService.setProperties(cat, properties); - - // Get the disposition schedule - DispositionSchedule ds = dispositionService.getDispositionSchedule(cat); - properties = nodeService.getProperties(ds.getNodeRef()); - properties.put(PROP_DISPOSITION_AUTHORITY, "Disposition Authority"); - properties.put(PROP_DISPOSITION_INSTRUCTIONS, "Test disposition"); - nodeService.setProperties(ds.getNodeRef(), properties); - - // Add cutoff disposition action - Map actionParams = new HashMap(2); - actionParams.put(PROP_DISPOSITION_ACTION_NAME, "cutoff"); - actionParams.put(PROP_DISPOSITION_PERIOD, new Period("day|1")); - dispositionService.addDispositionActionDefinition(ds, actionParams); - - // Add delete disposition action - actionParams = new HashMap(3); - actionParams.put(PROP_DISPOSITION_ACTION_NAME, "destroy"); - actionParams.put(PROP_DISPOSITION_PERIOD, new Period("immediately|0")); - actionParams.put(PROP_DISPOSITION_PERIOD_PROPERTY, QName.createQName("{http://www.alfresco.org/model/recordsmanagement/1.0}cutOffDate")); - dispositionService.addDispositionActionDefinition(ds, actionParams); - - System.out.println("Created category '" + name); - - // Create the record folders - for (int i = 0; i < RECORD_FOLDER_COUNT; i++) - { - // Create the series - createRecordFolder(cat, i); - } - } - - private void createRecordFolder(NodeRef cat, int index) throws Exception - { - String name = genName("folder-", index); - Map properties = new HashMap(2); - properties.put(ContentModel.PROP_NAME, name); - properties.put(PROP_IDENTIFIER, identifierService.generateIdentifier(TYPE_RECORD_FOLDER, cat)); - NodeRef rf = nodeService.createNode( - cat, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), - TYPE_RECORD_FOLDER, - properties).getChildRef(); - - // Need to close the transaction and reopen to kick off required initialisation behaviour - userTransaction.commit(); - userTransaction = transactionService.getUserTransaction(); - userTransaction.begin(); - - System.out.println("Created record folder '" + name); - - // Create the records - for (int i = 0; i < RECORD_COUNT; i++) - { - createRecord(rf, i); - } - - userTransaction.commit(); - userTransaction = transactionService.getUserTransaction(); - userTransaction.begin(); - } - - private void createRecord(NodeRef recordFolder, int index) throws Exception - { - String name = genName("record-", index, ".txt"); - Map properties = new HashMap(2); - properties.put(ContentModel.PROP_NAME, name); - NodeRef r = nodeService.createNode( - recordFolder, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), - ContentModel.TYPE_CONTENT, - properties).getChildRef(); - ContentWriter cw = contentService.getWriter(r, ContentModel.PROP_CONTENT, true); - cw.setEncoding("UTF-8"); - cw.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - cw.putContent("This is my records content"); - - System.out.println("Created record '" + name); - } - - private String genName(String prefix, int index) - { - return genName(prefix, index, ""); - } - - private String genName(String prefix, int index, String postfix) - { - StringBuffer buff = new StringBuffer(120); - buff.append(prefix) - .append(index) - .append(postfix); - return buff.toString(); - } -}