mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-10 14:11:58 +00:00
Compare commits
11 Commits
25.3.0.33
...
feature/AP
Author | SHA1 | Date | |
---|---|---|---|
|
59ef8cf488 | ||
|
8b16951754 | ||
|
c294018515 | ||
|
6e6b807c8f | ||
|
c1c9c284e6 | ||
|
fa8fe6e7aa | ||
|
4eb881e4a8 | ||
|
c862f0dc40 | ||
|
d4ae67cb49 | ||
|
64267619dc | ||
|
0345c11341 |
@@ -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
|
||||
|
@@ -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>
|
@@ -1,3 +1,2 @@
|
||||
# RM Schema number
|
||||
|
||||
version.rm.schema=3500
|
||||
version.rm.schema=7400
|
@@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user