Compare commits

...

11 Commits

Author SHA1 Message Date
bdwiwedi
59ef8cf488 APPS-1833 added some null check in service 2023-01-16 14:26:27 +05:30
bdwiwedi
8b16951754 APPS-1833 added global properties for batch size and query size 2023-01-13 00:27:34 +05:30
bdwiwedi
c294018515 APPS-1833 updated version properties 2023-01-12 17:49:15 +05:30
suneet-gupta
6e6b807c8f [APPS-1833] Refactored the code 2023-01-10 14:16:34 +05:30
suneet-gupta
c1c9c284e6 [APPS-1833] Refactored the code 2023-01-10 14:09:02 +05:30
suneet-gupta
fa8fe6e7aa Merge branch 'master' of github.com:Alfresco/alfresco-community-repo into feature/APPS-1833_PatchForUpdatingDispositionProperties 2023-01-10 11:46:30 +05:30
suneet-gupta
4eb881e4a8 [APPS-1833] Refactored the code 2023-01-10 11:45:20 +05:30
bdwiwedi
c862f0dc40 Merge remote-tracking branch 'origin/feature/APPS-1833_PatchForUpdatingDispositionProperties' into feature/APPS-1833_PatchForUpdatingDispositionProperties
# Conflicts:
#	amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v35/RMv35UpdateDispositionPropertiesPatch.java
2023-01-09 18:48:56 +05:30
bdwiwedi
d4ae67cb49 APPS-1833 added batch processing for getting all folder having disposition 2023-01-09 18:46:42 +05:30
suneet-gupta
64267619dc [APPS-1833] Refactored the code 2023-01-09 11:40:24 +05:30
bdwiwedi
0345c11341 APPS-1833 Patch for updating missing disposition properties in moved folder 2023-01-05 18:05:16 +05:30
5 changed files with 252 additions and 6 deletions

View File

@@ -139,3 +139,7 @@ content.metadata.async.extract.6.enabled=false
# Max number of entries returned in Record search view
rm.recordSearch.maxItems=500
#
# Max Batch size for updating the disposition properties in folders
rm.patch.v74.updateDispositionPropertiesPatch.batchSize=1000
rm.patch.v74.updateDispositionPropertiesPatch.querySize=5000

View File

@@ -0,0 +1,23 @@
<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- RM v7.4 Patches -->
<bean id="rm.updateDispositionPropertiesPatch"
parent="rm.parentModulePatch"
class="org.alfresco.module.org_alfresco_module_rm.patch.v74.RMv74UpdateDispositionPropertiesPatch">
<property name="description" value="Update missing disposition properties when folders moved from one category to another"/>
<property name="fixesToSchema" value="7400"/>
<property name="targetSchema" value="7401" />
<property name="nodeService" ref="nodeService"/>
<property name="batchSize" value="${rm.patch.v74.updateDispositionPropertiesPatch.batchSize}" />
<property name="querySize" value="${rm.patch.v74.updateDispositionPropertiesPatch.querySize}" />
<property name="nodeDAO" ref="nodeDAO"/>
<property name="behaviourFilter" ref="policyBehaviourFilter" />
<property name="recordsManagementQueryDAO" ref="recordsManagementQueryDAO"/>
<property name="recordsManagementSearchBehaviour" ref="recordsManagementSearchBehaviour"/>
<property name="dispositionService" ref="dispositionService"/>
</bean>
</beans>

View File

@@ -1,3 +1,2 @@
# RM Schema number
version.rm.schema=3500
version.rm.schema=7400

View File

@@ -0,0 +1,215 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2023 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.module.org_alfresco_module_rm.patch.v74;
import java.util.List;
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.model.behaviour.RecordsManagementSearchBehaviour;
import org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch;
import org.alfresco.module.org_alfresco_module_rm.query.RecordsManagementQueryDAO;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Patch to update disposition properties in all those folders which are moved from one category to another category
* and missing disposition properties
*/
public class RMv74UpdateDispositionPropertiesPatch extends AbstractModulePatch
{
private static final Logger LOGGER = LoggerFactory.getLogger(RMv74UpdateDispositionPropertiesPatch.class);
private NodeDAO nodeDAO;
private NodeService nodeService;
private BehaviourFilter behaviourFilter;
private RecordsManagementQueryDAO recordsManagementQueryDAO;
private RecordsManagementSearchBehaviour recordsManagementSearchBehaviour;
private DispositionService dispositionService;
/** How many operations in a transaction */
private int batchSize = 1000;
/** How many nodes do we query each time */
private int querySize = 5000;
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setNodeDAO(NodeDAO nodeDAO)
{
this.nodeDAO = nodeDAO;
}
public void setBatchSize(int batchSize)
{
this.batchSize = batchSize;
}
public void setQuerySize(int querySize)
{
this.querySize = querySize;
}
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
{
this.behaviourFilter = behaviourFilter;
}
public void setRecordsManagementQueryDAO(RecordsManagementQueryDAO recordsManagementQueryDAO)
{
this.recordsManagementQueryDAO = recordsManagementQueryDAO;
}
public void setRecordsManagementSearchBehaviour(RecordsManagementSearchBehaviour recordsManagementSearchBehaviour)
{
this.recordsManagementSearchBehaviour = recordsManagementSearchBehaviour;
}
public void setDispositionService(DispositionService dispositionService)
{
this.dispositionService = dispositionService;
}
@Override
public void applyInternal()
{
LOGGER.info("Starting execution of patch RMv74UpdateDispositionPropertiesPatch.");
behaviourFilter.disableBehaviour(ContentModel.ASPECT_AUDITABLE);
behaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE);
try
{
BatchProcessor batchProcessor = new BatchProcessor();
while (batchProcessor.hasNext())
{
batchProcessor.process();
}
LOGGER.info("Finished execution of patch RMv74UpdateDispositionPropertiesPatch ", batchProcessor.getTotalNodesProcessed());
}
finally
{
behaviourFilter.enableBehaviour(ContentModel.ASPECT_AUDITABLE);
behaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE);
}
}
private class BatchProcessor
{
long minNodeId;
long maxNodeId;
long nextNodeId;
long lastNodeProcessed;
int counter;
int totalCounter;
public BatchProcessor()
{
this.minNodeId = nodeDAO.getMinNodeId();
this.maxNodeId = nodeDAO.getMaxNodeId();
this.nextNodeId = minNodeId;
this.counter = 0;
this.lastNodeProcessed = 0;
}
public int getTotalNodesProcessed()
{
return totalCounter;
}
public boolean hasNext()
{
return nextNodeId <= maxNodeId;
}
public void process()
{
resetCounter();
transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
LOGGER.debug("^^^^^^^^^^^^^^^^^^^^^^^^^^calling process ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
Long currentNodeId = nextNodeId;
// While we haven't reached our batchSize and still have nodes to verify, keep processing
while (counter < batchSize && nextNodeId <= maxNodeId)
{
// Set upper value for query
Long upperNodeId = nextNodeId + querySize;
LOGGER.debug("calling update desposition batch process batch start node {} and nodes upper node ", nextNodeId,
nextNodeId, upperNodeId);
// Get nodes with aspects from node id nextNodeId to upperNodeId, ordered by node id and add/remove the aspect
updateDispositionPropertiesInFolders(currentNodeId, upperNodeId);
setNextNodeId();
if (nextNodeId >= maxNodeId)
{
// stop processing since we have meet our limit
break;
}
}
LOGGER.debug("Processed batch [{},{}]. Changed nodes: {}", currentNodeId, lastNodeProcessed, counter);
return true;
}, false, true);
}
private void updateDispositionPropertiesInFolders(Long currentNode, Long upperNodeId)
{
List<NodeRef> folders = recordsManagementQueryDAO.getRecordFoldersWithSchedules(currentNode, upperNodeId);
for (NodeRef folder : folders)
{
DispositionSchedule schedule = dispositionService.getDispositionSchedule(folder);
if (schedule != null && !schedule.isRecordLevelDisposition())
{
LOGGER.debug("Processing folder [{},{}]. moved with node ref: {}", folder);
recordsManagementSearchBehaviour.onAddDispositionLifecycleAspect(folder, null);
LOGGER.debug("Processed folder [{},{}]. moved with node ref: {}", folder);
}
lastNodeProcessed = nodeDAO.getNodePair(folder).getFirst();
incrementCounter();
}
}
private void setNextNodeId()
{
/*If the last query did not return results, the lastNodeProcessed will be lower than the previous
nextNodeId as it would be unchanged.*/
if (lastNodeProcessed < nextNodeId)
{
this.nextNodeId += querySize;
return;
}
// Next node id should be the last node id processed +1
this.nextNodeId = lastNodeProcessed + 1;
}
private void resetCounter()
{
this.counter = 0;
}
private void incrementCounter()
{
this.counter++;
this.totalCounter++;
}
}
}

View File

@@ -265,10 +265,15 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
public List<NodeRef> getRecordFoldersWithSchedules(Long start, Long end)
{
Map<String, Object> params = new HashMap<>(2);
params.put("processed", qnameDAO.getQName(ASPECT_DISPOSITION_PROCESSED)
.getFirst());
params.put("folderQnameId", qnameDAO.getQName(TYPE_RECORD_FOLDER)
.getFirst());
Pair<Long, QName> aspectPair = qnameDAO.getQName(ASPECT_DISPOSITION_PROCESSED);
if( aspectPair != null )
params.put("processed", aspectPair.getFirst());
Pair<Long, QName> recordFolderPair = qnameDAO.getQName(TYPE_RECORD_FOLDER);
if( recordFolderPair != null)
params.put("folderQnameId", recordFolderPair.getFirst())
;
params.put("start", start);
params.put("end", end);