mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
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
This commit is contained in:
@@ -278,6 +278,7 @@
|
||||
<aspect>rma:recordComponentIdentifier</aspect>
|
||||
<aspect>rma:commonRecordDetails</aspect>
|
||||
<aspect>rma:filePlanComponent</aspect>
|
||||
<aspect>rma:heldChildren</aspect>
|
||||
</mandatory-aspects>
|
||||
|
||||
</type>
|
||||
@@ -1131,6 +1132,20 @@
|
||||
</property>
|
||||
</properties>
|
||||
</aspect>
|
||||
|
||||
<!-- Number of held children, used to improve evaluation performance -->
|
||||
<!-- @since 2.2 -->
|
||||
<aspect name="rma:heldChildren">
|
||||
<title>Held children</title>
|
||||
<properties>
|
||||
<property name="rma:heldChildrenCount">
|
||||
<type>d:int</type>
|
||||
<protected>true</protected>
|
||||
<mandatory>true</mandatory>
|
||||
<default>0</default>
|
||||
</property>
|
||||
</properties>
|
||||
</aspect>
|
||||
|
||||
<!-- Helper aspect that can be used to keep a count -->
|
||||
<aspect name="rma:countable">
|
||||
|
@@ -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<ChildAssociationRef> 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<Integer>()
|
||||
{
|
||||
@Override
|
||||
public Integer doWork()
|
||||
{
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Integer>()
|
||||
{
|
||||
public Integer execute() throws Throwable
|
||||
{
|
||||
int heldCount = 0;
|
||||
|
||||
// NOTE: this process remains to 'patch' older systems to improve performance next time around
|
||||
List<ChildAssociationRef> 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<QName, Serializable> props = new HashMap<QName, Serializable>(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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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.
|
||||
|
@@ -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");
|
||||
|
@@ -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<Void>()
|
||||
{
|
||||
@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<Void>()
|
||||
{
|
||||
@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;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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
|
||||
* <p>
|
||||
* 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<String, Boolean> instanceOfCache = new HashMap<String, Boolean>();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<NodeRef> records = new ArrayList<NodeRef>(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<NodeRef> records = new ArrayList<NodeRef>(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<NodeRef> records = new ArrayList<NodeRef>(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<NodeRef> records = new ArrayList<NodeRef>(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<NodeRef> records = new ArrayList<NodeRef>(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));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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";
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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
|
||||
{
|
||||
}
|
@@ -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()
|
||||
{
|
||||
|
@@ -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()
|
||||
{
|
||||
|
@@ -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()
|
||||
{
|
||||
|
@@ -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()
|
||||
{
|
||||
|
@@ -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<RecordsManagementAuditEntry> entries = auditService.getAuditTrail(params);
|
||||
//assertNotNull(entries);
|
||||
//assertEquals(1, entries.size());
|
||||
|
||||
//RecordsManagementAuditEntry entry = entries.get(0);
|
||||
//assertEquals(record, entry.getNodeRef());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -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<NodeRef> 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;
|
||||
}
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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<NodeRef> recordCategories;
|
||||
private List<NodeRef> 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<Void>()
|
||||
{
|
||||
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<NodeRef>(ROOT_CATEGORY_COUNT);
|
||||
repeatInTransactionBatches(new RunAsWork<Void>()
|
||||
{
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
recordCategories.add(filePlanService.createRecordCategory(filePlan, GUID.generate()));
|
||||
return null;
|
||||
}
|
||||
}, ROOT_CATEGORY_COUNT);
|
||||
|
||||
// create record folders
|
||||
recordFolders = new ArrayList<NodeRef>(RECORD_FOLDER_COUNT);
|
||||
for (final NodeRef recordCategory : recordCategories)
|
||||
{
|
||||
repeatInTransactionBatches(new RunAsWork<Void>()
|
||||
{
|
||||
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<Void>()
|
||||
{
|
||||
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<Void> work, final int count) throws Exception
|
||||
{
|
||||
totalCount = 0;
|
||||
while (totalCount < count)
|
||||
{
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<QName, Serializable> properties = new HashMap<QName, Serializable>(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<QName, Serializable> properties = new HashMap<QName, Serializable>(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<QName, Serializable> actionParams = new HashMap<QName, Serializable>(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<QName, Serializable>(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<QName, Serializable> properties = new HashMap<QName, Serializable>(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<QName, Serializable> properties = new HashMap<QName, Serializable>(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();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user