diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml
index 9119c2f01c..e3010b1eb5 100644
--- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml
+++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml
@@ -71,6 +71,7 @@
+
@@ -123,6 +124,7 @@
+
diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml
index 3b5c7eee06..0b1b335fef 100644
--- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml
+++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml
@@ -389,6 +389,14 @@
+
+
+
+
+
+
+
+
@@ -397,6 +405,7 @@
parent="baseService"
class="org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanServiceImpl">
+
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanService.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanService.java
index f8b784d342..41bb9576b8 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanService.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanService.java
@@ -346,4 +346,4 @@ public interface FilePlanService
*/
NodeRef createRecordCategory(NodeRef parent, String name, Map properties);
-}
+}
\ No newline at end of file
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java
index 1194805168..a700b9dce9 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java
@@ -42,6 +42,7 @@ import org.alfresco.model.ContentModel;
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.role.FilePlanRoleService;
+import org.alfresco.module.org_alfresco_module_rm.util.RMContainerCacheManager;
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.domain.node.NodeDAO;
@@ -101,6 +102,9 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
/** Site service */
private SiteService siteService;
+ /** RM container cache manager **/
+ private RMContainerCacheManager rmContainerCacheManager;
+
/**
* Gets the file plan role service
*
@@ -174,6 +178,15 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
this.rootContainerCache = rootContainerCache;
}
+ /**
+ * @param rmContainerCacheManager RM container cache manager
+ *
+ */
+ public void setRmContainerCacheManager(RMContainerCacheManager rmContainerCacheManager)
+ {
+ this.rmContainerCacheManager = rmContainerCacheManager;
+ }
+
/**
* @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#getFilePlans(org.alfresco.service.cmr.repository.StoreRef)
*/
@@ -185,20 +198,30 @@ public class FilePlanServiceImpl extends ServiceBaseImpl
final Set results = new HashSet<>();
Set aspects = new HashSet<>(1);
aspects.add(ASPECT_RECORDS_MANAGEMENT_ROOT);
- getNodeDAO().getNodesWithAspects(aspects, Long.MIN_VALUE, Long.MAX_VALUE, new NodeDAO.NodeRefQueryCallback()
- {
- @Override
- public boolean handle(Pair nodePair)
- {
- NodeRef nodeRef = nodePair.getSecond();
- if (storeRef.equals(nodeRef.getStoreRef()))
- {
- results.add(nodeRef);
- }
- return true;
- }
- });
+ if (!rmContainerCacheManager.isCached(storeRef))
+ {
+ getNodeDAO().getNodesWithAspects(aspects, Long.MIN_VALUE, Long.MAX_VALUE, new NodeDAO.NodeRefQueryCallback()
+ {
+ @Override
+ public boolean handle(Pair nodePair)
+ {
+ NodeRef nodeRef = nodePair.getSecond();
+ if (storeRef.equals(nodeRef.getStoreRef()))
+ {
+ results.add(nodeRef);
+ rmContainerCacheManager.add(nodeRef);
+ }
+
+ return true;
+ }
+ });
+ }
+ else
+ {
+ return rmContainerCacheManager.get(storeRef);
+ }
+
return results;
}
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java
index 72a7894901..582c6ec1d6 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java
@@ -33,6 +33,7 @@ import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
+import org.alfresco.module.org_alfresco_module_rm.util.RMContainerCacheManager;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.policy.annotation.Behaviour;
@@ -55,7 +56,8 @@ import org.alfresco.service.namespace.QName;
defaultType = "rma:recordsManagementContainer"
)
public class RecordsManagementContainerType extends BaseBehaviourBean
- implements NodeServicePolicies.OnCreateChildAssociationPolicy
+ implements NodeServicePolicies.OnCreateChildAssociationPolicy,
+ NodeServicePolicies.OnDeleteChildAssociationPolicy
{
/** behaviour name */
private static final String BEHAVIOUR_NAME = "onCreateContainerType";
@@ -69,9 +71,21 @@ public class RecordsManagementContainerType extends BaseBehaviourBean
/** record folder service */
protected RecordFolderService recordFolderService;
+ /** RM container cache manager **/
+ private RMContainerCacheManager rmContainerCacheManager;
+
/** I18N */
private static final String MSG_CANNOT_CAST_TO_RM_TYPE = "rm.action.cast-to-rm-type";
+ /**
+ * @param rmContainerCacheManager RM container cache manager
+ *
+ */
+ public void setRmContainerCacheManager(RMContainerCacheManager rmContainerCacheManager)
+ {
+ this.rmContainerCacheManager = rmContainerCacheManager;
+ }
+
/**
* @param identifierService identifier service
*/
@@ -194,12 +208,48 @@ public class RecordsManagementContainerType extends BaseBehaviourBean
setIdenifierProperty(child);
}
}
+
+ if (rmContainerCacheManager != null)
+ {
+ rmContainerCacheManager.add(child);
+ }
}
return null;
}
});
+ }
+ /**
+ * Attempts to remove a deleted node from records management root cache
+ *
+ * @see org.alfresco.repo.node.NodeServicePolicies.OnDeleteAssociationPolicy#onDeleteAssociation(org.alfresco.service.cmr.repository.AssociationRef)
+ */
+ @Override
+ @Behaviour
+ (
+ kind = BehaviourKind.ASSOCIATION,
+ notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
+ )
+ public void onDeleteChildAssociation(ChildAssociationRef childAssocRef)
+ {
+
+ AuthenticationUtil.runAsSystem(new RunAsWork()
+ {
+ @Override
+ public Void doWork()
+ {
+ // Get the elements of the deleted association
+ final NodeRef child = childAssocRef.getChildRef();
+
+ if (rmContainerCacheManager != null)
+ {
+ rmContainerCacheManager.remove(child);
+ }
+
+ return null;
+ }
+ });
}
/**
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RmSiteType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RmSiteType.java
index 76b31f5250..c9f6e22ef4 100644
--- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RmSiteType.java
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RmSiteType.java
@@ -39,6 +39,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService;
+import org.alfresco.module.org_alfresco_module_rm.util.RMContainerCacheManager;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.policy.annotation.Behaviour;
@@ -73,7 +74,8 @@ public class RmSiteType extends BaseBehaviourBean
implements NodeServicePolicies.OnCreateNodePolicy,
NodeServicePolicies.OnUpdatePropertiesPolicy,
NodeServicePolicies.BeforeDeleteNodePolicy,
- NodeServicePolicies.OnCreateChildAssociationPolicy
+ NodeServicePolicies.OnCreateChildAssociationPolicy,
+ NodeServicePolicies.OnDeleteChildAssociationPolicy
{
/** Constant values */
public static final String COMPONENT_DOCUMENT_LIBRARY = "documentLibrary";
@@ -95,6 +97,9 @@ public class RmSiteType extends BaseBehaviourBean
private FilePlanType filePlanType;
+ /** RM container cache manager **/
+ private RMContainerCacheManager rmContainerCacheManager;
+
/** Map of file plan type's key'ed by corresponding site types */
protected Map mapFilePlanType = new HashMap<>(3);
@@ -105,7 +110,7 @@ public class RmSiteType extends BaseBehaviourBean
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
- }
+ }
/**
* @param recordsManagementSearchService records management search service
@@ -136,6 +141,15 @@ public class RmSiteType extends BaseBehaviourBean
this.filePlanType = filePlanType;
}
+ /**
+ * @param rmContainerCacheManager RM container cache manager
+ *
+ */
+ public void setRmContainerCacheManager(RMContainerCacheManager rmContainerCacheManager)
+ {
+ this.rmContainerCacheManager = rmContainerCacheManager;
+ }
+
/**
* Registers a file plan type for a specific site type.
*
@@ -310,6 +324,36 @@ public class RmSiteType extends BaseBehaviourBean
}
}
+ /**
+ * Handles site deletion in order to reset the records management root cache
+ *
+ * @param childAssocRef
+ *
+ * @see org.alfresco.repo.node.NodeServicePolicies.OnDeleteAssociationPolicy#onDeleteAssociation(org.alfresco.service.cmr.repository.AssociationRef)
+ */
+ @Override
+ @Behaviour
+ (
+ kind = BehaviourKind.ASSOCIATION
+ )
+ public void onDeleteChildAssociation(ChildAssociationRef childAssocRef)
+ {
+ AuthenticationUtil.runAsSystem(new RunAsWork()
+ {
+ @Override
+ public Void doWork()
+ {
+ // Resets RM Container Cache Manager
+ if (rmContainerCacheManager != null)
+ {
+ rmContainerCacheManager.reset();
+ }
+
+ return null;
+ }
+ });
+ }
+
/**
* Add the limitation of creating only one rma:filePlan or one dod:filePlan depending on the type of rm site.
* Let multiple cm:folder type be created under rm site.
@@ -339,6 +383,13 @@ public class RmSiteType extends BaseBehaviourBean
});
}
+ /**
+ * Handles the deletion node policy (alf:onDeleteNode), resetting the records management root cache
+ * and enabling file plan behavior as well
+ *
+ * @param childAssocRef
+ * @param isNodeArchived
+ */
@Behaviour
(
kind = BehaviourKind.CLASS,
@@ -347,6 +398,12 @@ public class RmSiteType extends BaseBehaviourBean
)
public void onDeleteNodeOnCommit(ChildAssociationRef childAssocRef, boolean isNodeArchived)
{
+ // Resets RM Container Cache Manager
+ if (rmContainerCacheManager != null)
+ {
+ rmContainerCacheManager.reset();
+ }
+
filePlanType.enable();
}
}
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/util/RMContainerCacheManager.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/util/RMContainerCacheManager.java
new file mode 100644
index 0000000000..2517198e02
--- /dev/null
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/util/RMContainerCacheManager.java
@@ -0,0 +1,162 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2020 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * 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 .
+ * #L%
+ */
+package org.alfresco.module.org_alfresco_module_rm.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
+import org.alfresco.repo.cache.SimpleCache;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.Pair;
+
+/**
+ * Provides operations to manipulate the records management root cache
+ *
+ * @author Tiago Salvado
+ *
+ * @see RecordsManagementModel
+ */
+public class RMContainerCacheManager implements RecordsManagementModel
+{
+ /** node service */
+ private NodeService nodeService;
+
+ /** root records management cache */
+ private SimpleCache, Set> cache;
+
+ /**
+ * @param nodeService
+ * node service
+ */
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ /**
+ * @param cache
+ */
+ public void setCache(SimpleCache, Set> cache)
+ {
+ this.cache = cache;
+ }
+
+ /**
+ * Verifies if there is cached nodes for supplied storeRef
+ *
+ * @param storeRef
+ * @return true if there are cached nodes, false otherwise
+ */
+ public boolean isCached(StoreRef storeRef)
+ {
+ return cache.contains(getKey(storeRef));
+ }
+
+ /**
+ * Obtains the cached nodes for supplied storeRef
+ *
+ * @param storeRef
+ * @return a set containing the cached nodes
+ */
+ public Set get(StoreRef storeRef)
+ {
+ return cache.get(getKey(storeRef));
+ }
+
+ /**
+ * Caches the supplied node
+ *
+ * @param nodeRef
+ */
+ public void add(NodeRef nodeRef)
+ {
+ if (nodeRef != null && nodeService.hasAspect(nodeRef, ASPECT_RECORDS_MANAGEMENT_ROOT))
+ {
+ Set entries;
+ Pair key = getKey(nodeRef.getStoreRef());
+
+ if (cache.contains(key))
+ {
+ entries = this.cache.get(key);
+ }
+ else
+ {
+ entries = new HashSet<>();
+ }
+
+ if (!entries.contains(nodeRef))
+ {
+ entries.add(nodeRef);
+ }
+
+ cache.put(key, entries);
+ }
+ }
+
+ /**
+ * Removes the supplied entry from the cache
+ *
+ * @param nodeRef
+ */
+ public void remove(NodeRef nodeRef)
+ {
+ if (nodeRef != null)
+ {
+ if (nodeService.hasAspect(nodeRef, ASPECT_RECORDS_MANAGEMENT_ROOT))
+ {
+ Pair key = getKey(nodeRef.getStoreRef());
+ if (cache.contains(key))
+ {
+ cache.get(key).remove(nodeRef);
+ }
+ }
+ }
+ }
+
+ /**
+ * Resets the cache entries
+ */
+ public void reset()
+ {
+ this.cache.clear();
+ }
+
+ /**
+ * Builds the cache key using the supplied storeRef
+ *
+ * @param storeRef
+ * @return a pair corresponding to the cache key
+ */
+ private Pair getKey(StoreRef storeRef)
+ {
+ return new Pair(storeRef, ASPECT_RECORDS_MANAGEMENT_ROOT.toString());
+ }
+}
diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java
index a8b31ff55e..1d81ab517c 100644
--- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java
+++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java
@@ -57,6 +57,7 @@ import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService;
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService;
import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService;
+import org.alfresco.module.org_alfresco_module_rm.util.RMContainerCacheManager;
import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordService;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.policy.PolicyComponent;
@@ -173,6 +174,9 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
protected InplaceRecordService inplaceRecordService;
protected RelationshipService relationshipService;
+ /** RM Container Cache Manager */
+ protected RMContainerCacheManager rmContainerCacheManager;
+
/** test utils */
protected UserAndGroupsUtils userAndGroupsUtils;
@@ -424,6 +428,9 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
holdService = (HoldService) applicationContext.getBean("HoldService");
inplaceRecordService = (InplaceRecordService) applicationContext.getBean("InplaceRecordService");
relationshipService = (RelationshipService) applicationContext.getBean("RelationshipService");
+
+ // RM Container Cache Manager
+ rmContainerCacheManager = (RMContainerCacheManager) applicationContext.getBean("rmContainerCacheManager");
}
/**
@@ -484,6 +491,11 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
{
siteService.deleteSite(collabSiteId);
}
+
+ if (rmContainerCacheManager != null)
+ {
+ rmContainerCacheManager.reset();
+ }
}
finally
{
@@ -936,7 +948,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
public void then() throws Exception { /** empty implementation */ }
public void after() throws Exception { /** empty implementation */ }
-
+
public void run() throws Exception
{
try