RM-2509: The destruction of electronic records is not possible as it gets ghosted before destruction.

* unit test added to reproduce issue



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@109872 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2015-08-11 04:18:12 +00:00
parent 05da180731
commit eace8ef026
5 changed files with 114 additions and 16 deletions

View File

@@ -19,6 +19,7 @@
<property name="eagerContentStoreCleaner" ref="eagerContentStoreCleaner" /> <property name="eagerContentStoreCleaner" ref="eagerContentStoreCleaner" />
<property name="dictionaryService" ref="dictionaryService" /> <property name="dictionaryService" ref="dictionaryService" />
<property name="nodeService" ref="nodeService" /> <property name="nodeService" ref="nodeService" />
<property name="behaviourFilter" ref="policyBehaviourFilter" />
<property name="cleansingEnabled" value="${rm.content.cleansing.enabled}" /> <property name="cleansingEnabled" value="${rm.content.cleansing.enabled}" />
</bean> </bean>

View File

@@ -28,6 +28,7 @@ import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassifi
import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.Behaviour;
import org.alfresco.repo.policy.annotation.BehaviourBean; import org.alfresco.repo.policy.annotation.BehaviourBean;
import org.alfresco.repo.policy.annotation.BehaviourKind; import org.alfresco.repo.policy.annotation.BehaviourKind;
@@ -71,6 +72,9 @@ public class ContentDestructionComponent implements NodeServicePolicies.BeforeDe
/** node service */ /** node service */
private NodeService nodeService; private NodeService nodeService;
/** behaviour filter */
private BehaviourFilter behaviourFilter;
/** indicates whether cleansing is enabled or not */ /** indicates whether cleansing is enabled or not */
private boolean cleansingEnabled = false; private boolean cleansingEnabled = false;
@@ -130,6 +134,14 @@ public class ContentDestructionComponent implements NodeServicePolicies.BeforeDe
this.cleansingEnabled = cleansingEnabled; this.cleansingEnabled = cleansingEnabled;
} }
/**
* @param behaviourFilter behaviour filter
*/
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
{
this.behaviourFilter = behaviourFilter;
}
/** /**
* @return true if cleansing is enabled, false otherwise * @return true if cleansing is enabled, false otherwise
*/ */
@@ -213,7 +225,7 @@ public class ContentDestructionComponent implements NodeServicePolicies.BeforeDe
if (childAssocTypes.contains(child.getTypeQName())) if (childAssocTypes.contains(child.getTypeQName()))
{ {
// destroy renditions content // destroy renditions content
destroyContent(nodeRef, false); destroyContent(child.getChildRef(), false);
} }
} }
} }
@@ -222,7 +234,8 @@ public class ContentDestructionComponent implements NodeServicePolicies.BeforeDe
/** /**
* Registers all content on the given node for destruction. * Registers all content on the given node for destruction.
* *
* @param nodeRef node reference * @param nodeRef node reference
* @param clearContentProperty if true then clear content property, otherwise false
*/ */
private void registerAllContentForDestruction(NodeRef nodeRef, boolean clearContentProperty) private void registerAllContentForDestruction(NodeRef nodeRef, boolean clearContentProperty)
{ {
@@ -250,7 +263,16 @@ public class ContentDestructionComponent implements NodeServicePolicies.BeforeDe
// clear the property // clear the property
if (clearContentProperty) if (clearContentProperty)
{ {
nodeService.removeProperty(nodeRef, entry.getKey()); // disable behaviours to ensure no side effects
behaviourFilter.disableBehaviour();
try
{
nodeService.removeProperty(nodeRef, entry.getKey());
}
finally
{
behaviourFilter.enableBehaviour();
}
} }
} }
} }

View File

@@ -18,8 +18,13 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.test.integration.destroy; package org.alfresco.module.org_alfresco_module_rm.test.integration.destroy;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.model.ContentModel;
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.action.impl.DestroyAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationAspectProperties; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationAspectProperties;
@@ -30,10 +35,13 @@ import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils;
import org.alfresco.module.org_alfresco_module_rm.test.util.TestContentCleanser; import org.alfresco.module.org_alfresco_module_rm.test.util.TestContentCleanser;
import org.alfresco.repo.content.ContentStore; import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.rendition.RenditionService;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.test.AlfrescoTest; import org.alfresco.test.AlfrescoTest;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
@@ -51,6 +59,7 @@ public class DestroyContentTest extends BaseRMTestCase
private TestContentCleanser contentCleanser; private TestContentCleanser contentCleanser;
private EagerContentStoreCleaner eagerContentStoreCleaner; private EagerContentStoreCleaner eagerContentStoreCleaner;
private ContentDestructionComponent contentDestructionComponent; private ContentDestructionComponent contentDestructionComponent;
private RenditionService renditionService;
@Override @Override
protected void initServices() protected void initServices()
@@ -60,6 +69,7 @@ public class DestroyContentTest extends BaseRMTestCase
contentCleanser = (TestContentCleanser)applicationContext.getBean(BEAN_NAME_CONTENT_CLEANSER); contentCleanser = (TestContentCleanser)applicationContext.getBean(BEAN_NAME_CONTENT_CLEANSER);
eagerContentStoreCleaner = (EagerContentStoreCleaner)applicationContext.getBean("eagerContentStoreCleaner"); eagerContentStoreCleaner = (EagerContentStoreCleaner)applicationContext.getBean("eagerContentStoreCleaner");
contentDestructionComponent = (ContentDestructionComponent)applicationContext.getBean("contentDestructionComponent"); contentDestructionComponent = (ContentDestructionComponent)applicationContext.getBean("contentDestructionComponent");
renditionService = (RenditionService)applicationContext.getBean("renditionService");
// set the test content store cleaner // set the test content store cleaner
eagerContentStoreCleaner.setContentCleanser(contentCleanser); eagerContentStoreCleaner.setContentCleanser(contentCleanser);
@@ -92,7 +102,14 @@ public class DestroyContentTest extends BaseRMTestCase
false, false,
true); true);
destroyableFolder = recordFolderService.createRecordFolder(recordCategoryFolderLevel, GUID.generate()); destroyableFolder = recordFolderService.createRecordFolder(recordCategoryFolderLevel, GUID.generate());
subRecord = utils.createRecord(destroyableFolder, GUID.generate(), GUID.generate());
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_TITLE, GUID.generate());
InputStream is = System.class.getResourceAsStream("/alfresco/test/content/Image.jpg");
subRecord = utils.createRecord(destroyableFolder, GUID.generate(), props, MimetypeMap.MIMETYPE_IMAGE_JPEG, is);
renditionService.render(subRecord, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "medium"));
utils.completeRecord(subRecord); utils.completeRecord(subRecord);
utils.completeEvent(destroyableFolder, CommonRMTestUtils.DEFAULT_EVENT_NAME); utils.completeEvent(destroyableFolder, CommonRMTestUtils.DEFAULT_EVENT_NAME);
rmActionService.executeRecordsManagementAction(destroyableFolder, CutOffAction.NAME); rmActionService.executeRecordsManagementAction(destroyableFolder, CutOffAction.NAME);

View File

@@ -18,6 +18,7 @@
*/ */
package org.alfresco.module.org_alfresco_module_rm.test.util; package org.alfresco.module.org_alfresco_module_rm.test.util;
import java.io.InputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@@ -190,11 +191,26 @@ public class CommonRMTestUtils implements RecordsManagementModel
return dispositionSchedule; return dispositionSchedule;
} }
/**
* Helper method to create a record in a record folder.
*
* @param recordFolder record folder
* @param name name of record
* @return {@link NodeRef} record node reference
*/
public NodeRef createRecord(NodeRef recordFolder, String name) public NodeRef createRecord(NodeRef recordFolder, String name)
{ {
return createRecord(recordFolder, name, null, "Some test content"); return createRecord(recordFolder, name, null, "Some test content");
} }
/**
* Helper method to create a record in a record folder.
*
* @param recordFolder record folder
* @param name name of the record
* @param title title of the record
* @return {@link NodeRef} record node reference
*/
public NodeRef createRecord(NodeRef recordFolder, String name, String title) public NodeRef createRecord(NodeRef recordFolder, String name, String title)
{ {
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1); Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
@@ -202,7 +218,56 @@ public class CommonRMTestUtils implements RecordsManagementModel
return createRecord(recordFolder, name, props, "Some test content"); return createRecord(recordFolder, name, props, "Some test content");
} }
/**
* Helper method to create a record in a record folder.
*
* @param recordFolder record folder
* @param name name of record
* @param properties properties of the record
* @param content content of the record
* @return {@link NodeRef} record node reference
*/
public NodeRef createRecord(NodeRef recordFolder, String name, Map<QName, Serializable> properties, String content) public NodeRef createRecord(NodeRef recordFolder, String name, Map<QName, Serializable> properties, String content)
{
// Create the record
NodeRef record = createRecordImpl(recordFolder, name, properties);
// Set the content
ContentWriter writer = contentService.getWriter(record, ContentModel.PROP_CONTENT, true);
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding("UTF-8");
writer.putContent(content);
return record;
}
/**
* Helper method to create a record in a record folder.
*
* @param recordFolder record folder
* @param name name of record
* @param properties properties of the record
* @param content content of the record
* @return {@link NodeRef} record node reference
*/
public NodeRef createRecord(NodeRef recordFolder, String name, Map<QName, Serializable> properties, String mimetype, InputStream content)
{
// Create the record
NodeRef record = createRecordImpl(recordFolder, name, properties);
// Set the content
ContentWriter writer = contentService.getWriter(record, ContentModel.PROP_CONTENT, true);
writer.setMimetype(mimetype);
writer.setEncoding("UTF-8");
writer.putContent(content);
return record;
}
/**
* Helper to consolidate creation of contentless record
*/
private NodeRef createRecordImpl(NodeRef recordFolder, String name, Map<QName, Serializable> properties)
{ {
// Create the document // Create the document
if (properties == null) if (properties == null)
@@ -213,19 +278,12 @@ public class CommonRMTestUtils implements RecordsManagementModel
{ {
properties.put(ContentModel.PROP_NAME, name); properties.put(ContentModel.PROP_NAME, name);
} }
NodeRef recordOne = nodeService.createNode(recordFolder, NodeRef record = nodeService.createNode(recordFolder,
ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
ContentModel.TYPE_CONTENT, ContentModel.TYPE_CONTENT,
properties).getChildRef(); properties).getChildRef();
return record;
// Set the content
ContentWriter writer = contentService.getWriter(recordOne, ContentModel.PROP_CONTENT, true);
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding("UTF-8");
writer.putContent(content);
return recordOne;
} }
/** /**

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 KiB