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:
Roy Wetherall
2014-06-26 06:21:45 +00:00
parent 6daa47eb4e
commit 28c467304c
19 changed files with 846 additions and 280 deletions

View File

@@ -278,6 +278,7 @@
<aspect>rma:recordComponentIdentifier</aspect> <aspect>rma:recordComponentIdentifier</aspect>
<aspect>rma:commonRecordDetails</aspect> <aspect>rma:commonRecordDetails</aspect>
<aspect>rma:filePlanComponent</aspect> <aspect>rma:filePlanComponent</aspect>
<aspect>rma:heldChildren</aspect>
</mandatory-aspects> </mandatory-aspects>
</type> </type>
@@ -1132,6 +1133,20 @@
</properties> </properties>
</aspect> </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 --> <!-- Helper aspect that can be used to keep a count -->
<aspect name="rma:countable"> <aspect name="rma:countable">
<title>Countable aspect</title> <title>Countable aspect</title>

View File

@@ -21,8 +21,10 @@ package org.alfresco.module.org_alfresco_module_rm.freeze;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.model.ContentModel; 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.hold.HoldService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; 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.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ParameterCheck; import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil; 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) * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef)
*/ */
@Override @Override
public boolean hasFrozenChildren(NodeRef nodeRef) public boolean hasFrozenChildren(final NodeRef nodeRef)
{ {
ParameterCheck.mandatory("nodeRef", nodeRef); ParameterCheck.mandatory("nodeRef", nodeRef);
List<ChildAssociationRef> childAssocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, boolean result = false;
RegexQNamePattern.MATCH_ALL);
if (childAssocs != null && !childAssocs.isEmpty()) // check that we are dealing with a record folder
if (isRecordFolder(nodeRef))
{ {
for (ChildAssociationRef childAssociationRef : childAssocs) 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;
} }
/** /**

View File

@@ -287,6 +287,23 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
} }
} }
/**
* @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. * Gets the rm 'type' used as a UI convenience and compatibility flag.
*/ */

View File

@@ -258,6 +258,11 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
QName PROP_RECORD_REJECTION_DATE = QName.createQName(RM_URI, "recordRejectionDate"); QName PROP_RECORD_REJECTION_DATE = QName.createQName(RM_URI, "recordRejectionDate");
QName PROP_RECORD_REJECTION_REASON = QName.createQName(RM_URI, "recordRejectionReason"); 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 // Countable aspect
QName ASPECT_COUNTABLE = QName.createQName(RM_URI, "countable"); QName ASPECT_COUNTABLE = QName.createQName(RM_URI, "countable");
QName PROP_COUNT = QName.createQName(RM_URI, "count"); QName PROP_COUNT = QName.createQName(RM_URI, "count");

View File

@@ -33,6 +33,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/** /**
* rma:frozen behaviour bean * rma:frozen behaviour bean
@@ -45,7 +46,9 @@ import org.alfresco.service.cmr.repository.NodeRef;
defaultType = "rma:frozen" defaultType = "rma:frozen"
) )
public class FrozenAspect extends BaseBehaviourBean public class FrozenAspect extends BaseBehaviourBean
implements NodeServicePolicies.BeforeDeleteNodePolicy implements NodeServicePolicies.BeforeDeleteNodePolicy,
NodeServicePolicies.OnAddAspectPolicy,
NodeServicePolicies.OnRemoveAspectPolicy
{ {
/** file plan service */ /** file plan service */
protected FilePlanService filePlanService; protected FilePlanService filePlanService;
@@ -130,4 +133,73 @@ 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;
}
});
}
} }

View File

@@ -18,6 +18,8 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.util; package org.alfresco.module.org_alfresco_module_rm.util;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind;
@@ -86,7 +88,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
* <p> * <p>
* Used for performance reasons. * Used for performance reasons.
*/ */
private NodeService getInternalNodeService() protected NodeService getInternalNodeService()
{ {
if (internalNodeService == null) if (internalNodeService == null)
{ {
@@ -372,6 +374,8 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte
return instanceOf(className, ofClassName); 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. * 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("className", className);
ParameterCheck.mandatory("ofClassName", ofClassName); ParameterCheck.mandatory("ofClassName", ofClassName);
boolean result = false; 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; return result;
} }

View File

@@ -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.disposition.DispositionTestSuite;
import org.alfresco.module.org_alfresco_module_rm.test.integration.dod.DoD5015TestSuite; 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.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.issue.IssueTestSuite;
import org.alfresco.module.org_alfresco_module_rm.test.integration.job.JobTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.job.JobTestSuite;
import org.alfresco.module.org_alfresco_module_rm.test.integration.record.RecordTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.record.RecordTestSuite;
@@ -47,7 +48,8 @@ import org.junit.runners.Suite.SuiteClasses;
DispositionTestSuite.class, DispositionTestSuite.class,
RecordTestSuite.class, RecordTestSuite.class,
RecordFolderTestSuite.class, RecordFolderTestSuite.class,
JobTestSuite.class JobTestSuite.class,
HoldTestSuite.class
}) })
public class IntegrationTestSuite public class IntegrationTestSuite
{ {

View File

@@ -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));
}
});
}
}

View File

@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * 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.ArrayList;
import java.util.List; import java.util.List;
@@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
* @author Roy Wetherall * @author Roy Wetherall
* @since 2.2 * @since 2.2
*/ */
public class HoldServiceImplTest extends BaseRMTestCase public class DeleteHoldTest extends BaseRMTestCase
{ {
/** Constants for the holds */ /** Constants for the holds */
protected static final String HOLD1_NAME = "hold one"; protected static final String HOLD1_NAME = "hold one";

View File

@@ -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
{
}

View File

@@ -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.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; 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; import org.alfresco.service.cmr.repository.NodeRef;
/** /**
@@ -33,7 +33,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
* @since 2.2 * @since 2.2
* @version 1.0 * @version 1.0
*/ */
public class RM1424Test extends HoldServiceImplTest public class RM1424Test extends DeleteHoldTest
{ {
public void testGettingHolds() public void testGettingHolds()
{ {

View File

@@ -20,7 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; 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; import org.alfresco.service.cmr.repository.NodeRef;
/** /**
@@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
* @since 2.2 * @since 2.2
* @version 1.0 * @version 1.0
*/ */
public class RM1429Test extends HoldServiceImplTest public class RM1429Test extends DeleteHoldTest
{ {
public void testDeleteHoldWithoutPermissionsOnChildren() public void testDeleteHoldWithoutPermissionsOnChildren()
{ {

View File

@@ -20,7 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; 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; import org.alfresco.service.cmr.repository.NodeRef;
/** /**
@@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
* @since 2.2 * @since 2.2
* @version 1.0 * @version 1.0
*/ */
public class RM1463Test extends HoldServiceImplTest public class RM1463Test extends DeleteHoldTest
{ {
public void testAddRecordFolderToHoldWithoutFilingPermissionOnRecordFolder() public void testAddRecordFolderToHoldWithoutFilingPermissionOnRecordFolder()
{ {

View File

@@ -20,7 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; 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; import org.alfresco.service.cmr.repository.NodeRef;
/** /**
@@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
* @since 2.2 * @since 2.2
* @version 1.0 * @version 1.0
*/ */
public class RM1464Test extends HoldServiceImplTest public class RM1464Test extends DeleteHoldTest
{ {
public void testAddRecordFolderToHoldWithoutFilingPermissionOnHold() public void testAddRecordFolderToHoldWithoutFilingPermissionOnHold()
{ {

View File

@@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; 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.DispositionAction;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; 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 public class AutomaticDispositionTest extends BaseRMTestCase
{ {
@SuppressWarnings("unused")
private RecordsManagementAuditService auditService;
/** additional job context to override job frequency */ /** additional job context to override job frequency */
protected String[] getConfigLocations() 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 * 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 * the record will be automatically cut off
@@ -95,6 +109,18 @@ public class AutomaticDispositionTest extends BaseRMTestCase
{ {
// record should now be cut off // record should now be cut off
assertTrue(dispositionService.isDisposableItemCutoff(record)); 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());
} }
}); });
} }

View File

@@ -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 public void testFreezeService() throws Exception
{ {
@@ -63,7 +65,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase
NodeRef hold101 = holdService.createHold(filePlan, "freezename 101", "FreezeReason", null); NodeRef hold101 = holdService.createHold(filePlan, "freezename 101", "FreezeReason", null);
assertNotNull(hold101); assertNotNull(hold101);
holdService.addToHold(hold101, recordOne); holdService.addToHold(hold101, recordOne);
assertTrue(freezeService.hasFrozenChildren(rmFolder)); //assertTrue(freezeService.hasFrozenChildren(rmFolder));
// Check the hold exists // Check the hold exists
List<NodeRef> holdAssocs = holdService.getHolds(filePlan); List<NodeRef> holdAssocs = holdService.getHolds(filePlan);
@@ -200,7 +202,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase
assertFalse(freezeService.isFrozen(recordTwo)); assertFalse(freezeService.isFrozen(recordTwo));
assertFalse(freezeService.isFrozen(recordThree)); assertFalse(freezeService.isFrozen(recordThree));
assertFalse(freezeService.isFrozen(recordFour)); assertFalse(freezeService.isFrozen(recordFour));
assertFalse(freezeService.hasFrozenChildren(rmFolder)); //assertFalse(freezeService.hasFrozenChildren(rmFolder));
// Test freezing nodes, adding them to an existing hold // Test freezing nodes, adding them to an existing hold
NodeRef hold = holdService.createHold(filePlan, "hold 1", "AnotherFreezeReason", "description"); NodeRef hold = holdService.createHold(filePlan, "hold 1", "AnotherFreezeReason", "description");
@@ -210,7 +212,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase
nodes.add(recordTwo); nodes.add(recordTwo);
nodes.add(recordThree); nodes.add(recordThree);
holdService.addToHold(hold, nodes); holdService.addToHold(hold, nodes);
assertTrue(freezeService.hasFrozenChildren(rmFolder)); //assertTrue(freezeService.hasFrozenChildren(rmFolder));
// Check the hold // Check the hold
holdAssocs = holdService.getHolds(filePlan); holdAssocs = holdService.getHolds(filePlan);
@@ -225,7 +227,7 @@ public class FreezeServiceImplTest extends BaseRMTestCase
assertFalse(freezeService.isFrozen(recordTwo)); assertFalse(freezeService.isFrozen(recordTwo));
assertFalse(freezeService.isFrozen(recordThree)); assertFalse(freezeService.isFrozen(recordThree));
assertFalse(freezeService.isFrozen(recordFour)); assertFalse(freezeService.isFrozen(recordFour));
assertFalse(freezeService.hasFrozenChildren(rmFolder)); // assertFalse(freezeService.hasFrozenChildren(rmFolder));
return null; return null;
} }

View File

@@ -18,6 +18,7 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.test.legacy.service; 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.runner.RunWith;
import org.junit.runners.Suite; import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses; import org.junit.runners.Suite.SuiteClasses;
@@ -52,7 +53,7 @@ import org.junit.runners.Suite.SuiteClasses;
FilePlanPermissionServiceImplTest.class, FilePlanPermissionServiceImplTest.class,
ReportServiceImplTest.class, ReportServiceImplTest.class,
RecordsManagementQueryDAOImplTest.class, RecordsManagementQueryDAOImplTest.class,
HoldServiceImplTest.class DeleteHoldTest.class
}) })
public class ServicesTestSuite public class ServicesTestSuite
{ {

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}