[feature/MNT-24127] EndpointToCalculateFolderSize

This commit is contained in:
mohit-singh4
2024-07-22 09:15:19 +05:30
parent b47e0551cb
commit 88d10f2f4f
8 changed files with 72 additions and 58 deletions

View File

@@ -60,6 +60,12 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test dependencies --> <!-- Test dependencies -->
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>

View File

@@ -27,8 +27,10 @@ package org.alfresco.rest.api.nodes;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.action.executer.NodeSizeActionExecuter; import org.alfresco.repo.action.executer.NodeSizeActionExecuter;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.impl.FolderSizeImpl;
import org.alfresco.rest.api.model.Node; import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.api.model.NodePermissions; import org.alfresco.rest.api.model.NodePermissions;
import org.alfresco.rest.framework.WebApiDescription; import org.alfresco.rest.framework.WebApiDescription;
@@ -42,9 +44,8 @@ import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.ActionStatus;
import org.alfresco.service.cmr.action.ActionTrackingService; import org.alfresco.service.cmr.action.ActionTrackingService;
import org.alfresco.service.cmr.action.ExecutionDetails;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
@@ -56,8 +57,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.Status;
import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@@ -76,7 +78,11 @@ public class NodeFolderSizeRelation implements CalculateSize<Map<String, Object>
private ActionService actionService; private ActionService actionService;
private ActionTrackingService actionTrackingService; private ActionTrackingService actionTrackingService;
private Action folderSizeAction; private Action folderSizeAction;
private FolderSizeImpl folderSizeImpl;
private NodeRef nodeRef;
private String exceptionMessage = "Invalid parameter: value of nodeId is invalid"; private String exceptionMessage = "Invalid parameter: value of nodeId is invalid";
/** the shared cache that will hold action data */
private static SimpleCache<Serializable,Object> sharedCache;
/** /**
* The logger * The logger
@@ -124,6 +130,11 @@ public class NodeFolderSizeRelation implements CalculateSize<Map<String, Object>
this.actionTrackingService = actionTrackingService; this.actionTrackingService = actionTrackingService;
} }
public void setSharedCache(SimpleCache<Serializable, Object> sharedCache)
{
this.sharedCache = sharedCache;
}
/** /**
* Folder Size - returns size of a folder. * Folder Size - returns size of a folder.
* *
@@ -139,7 +150,7 @@ public class NodeFolderSizeRelation implements CalculateSize<Map<String, Object>
@WebApiDescription(title = "Calculating Folder Size", description = "Calculating size of a folder", successStatus = Status.STATUS_ACCEPTED) @WebApiDescription(title = "Calculating Folder Size", description = "Calculating size of a folder", successStatus = Status.STATUS_ACCEPTED)
public Map<String, Object> createById(String nodeId, Parameters params) public Map<String, Object> createById(String nodeId, Parameters params)
{ {
NodeRef nodeRef = nodes.validateNode(nodeId); nodeRef = nodes.validateNode(nodeId);
int maxItems = Math.min(params.getPaging().getMaxItems(), 1000); int maxItems = Math.min(params.getPaging().getMaxItems(), 1000);
QName qName = nodeService.getType(nodeRef); QName qName = nodeService.getType(nodeRef);
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
@@ -153,49 +164,33 @@ public class NodeFolderSizeRelation implements CalculateSize<Map<String, Object>
try try
{ {
folderSizeAction = actionService.createAction(NodeSizeActionExecuter.NAME); this.folderSizeImpl = new FolderSizeImpl(actionService, actionTrackingService, nodeService);
folderSizeAction.setTrackStatus(true); return this.folderSizeImpl.executingAsynchronousFolderAction(maxItems, nodeRef, result, sharedCache);
folderSizeAction.setExecuteAsynchronously(true);
folderSizeAction.setParameterValue(NodeSizeActionExecuter.PAGE_SIZE, maxItems);
folderSizeAction.setParameterValue(NodeSizeActionExecuter.RESULT, "IN-PROGRESS");
actionService.executeAction(folderSizeAction, nodeRef, false, true);
LOG.info(" Executing ActionExecutor in NodeFolderSizeRelation:createById ");
List<ExecutionSummary> executionSummaryList = actionTrackingService.getExecutingActions(NodeSizeActionExecuter.NAME);
ExecutionDetails executionDetails = actionTrackingService.getExecutionDetails(executionSummaryList.get(0));
result.put("executionId", executionDetails.getActionId());
return result;
} }
catch (Exception ex) catch (Exception ex)
{ {
LOG.error("Exception occurred in NodeFolderSizeRelation:createById {}", ex.getMessage()); LOG.error("Exception occurred in NodeFolderSizeRelation:createById {}", ex.getMessage());
throw ex; // This rethrows with the original stack trace preserved. throw new AlfrescoRuntimeException("Exception occurred in NodeFolderSizeRelation:createById");
} }
} }
@Override @Override
@WebApiDescription(title = "Returns Folder Node Size", description = "Returning a Folder Node Size") @WebApiDescription(title = "Returns Folder Node Size", description = "Returning a Folder Node Size")
@WebApiParameters({@WebApiParam(name = "nodeId", title = "The unique id of the Node being addressed", description = "A single node id")}) @WebApiParameters({@WebApiParam(name = "executionId", title = "The unique id of Execution Job", description = "A single execution id")})
public Map<String, Object> readById(String nodeId, String id, Parameters parameters) public Map<String, Object> readById(String executionId, String id, Parameters parameters)
{ {
NodeRef nodeRef = nodes.validateNode(nodeId);
// Check node type.
QName qName = nodeService.getType(nodeRef);
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
validatePermissions(nodeRef, nodeId);
validateAction();
if(!"folder".equals(qName.getLocalName()))
{
throw new InvalidNodeTypeException(exceptionMessage);
}
try try
{ {
LOG.info("Retrieving OUTPUT from ActionExecutor in NodeFolderSizeRelation:readById"); LOG.info("Retrieving OUTPUT from NodeSizeActionExecutor - NodeFolderSizeRelation:readById");
if(folderSizeAction!=null) if(nodeRef!=null)
{ {
Object resultAction = folderSizeAction.getParameterValue(NodeSizeActionExecuter.RESULT); //Action extractedResult = this.folderSizeImpl.extractingActionsResult(nodeRef, executionId);
result = getResult(resultAction, nodeId); Action actionData = (Action) sharedCache.get(executionId);
Action extractedResult = this.folderSizeImpl.getAction(nodeRef, executionId);
result = getResult(extractedResult);
} }
else else
{ {
@@ -210,7 +205,7 @@ public class NodeFolderSizeRelation implements CalculateSize<Map<String, Object>
} }
} }
private Map<String, Object> getResult(Object resultAction, String nodeId) private Map<String, Object> getResult(Action resultAction)
{ {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
@@ -220,20 +215,17 @@ public class NodeFolderSizeRelation implements CalculateSize<Map<String, Object>
} }
else else
{ {
Map<String, Object> mapResult = (Map<String, Object>) resultAction; ActionStatus actionStatus = resultAction.getExecutionStatus();
if (!mapResult.containsKey("size")) if(ActionStatus.Pending.name().equals(actionStatus.name()))
{ {
result.put("status", "IN-PROGRESS"); result.put("status", "IN-PROGRESS");
} }
else if (mapResult.get("id").equals(nodeId))
{
mapResult.put("status", "COMPLETED");
result = mapResult;
}
else else
{ {
result.put("status", "NOT-INITIATED"); Map<String, Object> mapResult = (Map<String, Object>) resultAction.getParameterValue(NodeSizeActionExecuter.RESULT);
mapResult.put("status","COMPLETED");
result = mapResult;
} }
} }
return result; return result;

View File

@@ -294,6 +294,7 @@ public class ResourceInspector
findOperation(MultiPartRelationshipResourceAction.Create.class, POST, helper); findOperation(MultiPartRelationshipResourceAction.Create.class, POST, helper);
findOperation(RelationshipResourceAction.CalculateSize.class, POST, helper); findOperation(RelationshipResourceAction.CalculateSize.class, POST, helper);
findOperation(RelationshipResourceAction.CalculateSize.class, GET, helper);
boolean noAuth = resource.isAnnotationPresent(WebApiNoAuth.class); boolean noAuth = resource.isAnnotationPresent(WebApiNoAuth.class);
if (noAuth) if (noAuth)

View File

@@ -1777,5 +1777,6 @@
<property name="nodeService" ref="nodeService" /> <property name="nodeService" ref="nodeService" />
<property name="actionService" ref="ActionService"/> <property name="actionService" ref="ActionService"/>
<property name="actionTrackingService" ref="actionTrackingService" /> <property name="actionTrackingService" ref="actionTrackingService" />
<property name="sharedCache" ref="folderSizeSharedCache" />
</bean> </bean>
</beans> </beans>

View File

@@ -644,14 +644,4 @@ public class InspectorTests
assertEquals(Status.STATUS_NOT_MODIFIED,ResourceInspector.validSuccessCode(HttpMethod.DELETE, Status.STATUS_NOT_MODIFIED)); assertEquals(Status.STATUS_NOT_MODIFIED,ResourceInspector.validSuccessCode(HttpMethod.DELETE, Status.STATUS_NOT_MODIFIED));
} }
@Test
public void testCalculateSizeRelation()
{
List<ResourceMetadata> metainfo = ResourceInspector.inspect(NodeFolderSizeRelation.class);
assertTrue("Must be one ResourceMetadata",!metainfo.isEmpty());
ResourceMetadata metaData = metainfo.get(0);
assertNotNull(metaData);
ResourceOperation op = metaData.getOperation(HttpMethod.POST);
assertNotNull("NodeFolderSizeRelation supports POST", op);
}
} }

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.action.executer;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterizedItemAbstractBase; import org.alfresco.repo.action.ParameterizedItemAbstractBase;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
@@ -44,6 +45,7 @@ import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -63,6 +65,8 @@ public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
public static final String PAGE_SIZE = "page-size"; public static final String PAGE_SIZE = "page-size";
public static final String RESULT = "size-result"; public static final String RESULT = "size-result";
public static final String ERROR = "exception"; public static final String ERROR = "exception";
public static final String CACHE_REF = "sharedCache";
public static final Map<String,Action> actionsRecords = new HashMap<>();
/** /**
* The node service * The node service
@@ -99,9 +103,10 @@ public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
* @see ActionExecuter#execute(Action, NodeRef) * @see ActionExecuter#execute(Action, NodeRef)
*/ */
@Override @Override
public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) public void executeImpl(Action nodeAction, NodeRef actionedUponNodeRef)
{ {
Serializable serializable = ruleAction.getParameterValue(PAGE_SIZE); Serializable serializable = nodeAction.getParameterValue(PAGE_SIZE);
Serializable serializedCache = nodeAction.getParameterValue(CACHE_REF);
int maxItems; int maxItems;
Map<String,Object> response = new HashMap<>(); Map<String,Object> response = new HashMap<>();
@@ -112,7 +117,7 @@ public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
catch (NumberFormatException e) catch (NumberFormatException e)
{ {
LOG.error("Exception occurred while parsing String to INT: {}", e.getMessage()); LOG.error("Exception occurred while parsing String to INT: {}", e.getMessage());
ruleAction.setParameterValue(ERROR, e.getMessage()); nodeAction.setParameterValue(ERROR, e.getMessage());
throw e; throw e;
} }
@@ -129,6 +134,7 @@ public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
searchParameters.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); searchParameters.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
searchParameters.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); searchParameters.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
searchParameters.setQuery(query); searchParameters.setQuery(query);
//searchParameters.addFacetQuery();
try try
{ {
@@ -175,7 +181,7 @@ public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
catch (RuntimeException ex) catch (RuntimeException ex)
{ {
LOG.error("Exception occurred in NodeSizeActionExecutor:results {}", ex.getMessage()); LOG.error("Exception occurred in NodeSizeActionExecutor:results {}", ex.getMessage());
ruleAction.setParameterValue(ERROR, ex.getMessage()); nodeAction.setParameterValue(ERROR, ex.getMessage());
throw ex; throw ex;
} }
@@ -185,12 +191,15 @@ public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
String formattedTimestamp = eventTimestamp.format(formatter); String formattedTimestamp = eventTimestamp.format(formatter);
response.put("id", nodeRef.getId()); response.put("id", nodeRef.getId());
response.put("size", totalSize); response.put("size", totalSize);
response.put("calculatedAtTime", formattedTimestamp); response.put("calculatedAt", formattedTimestamp);
response.put("numberOfFiles", results != null ? results.getNodeRefs().size() : 0); response.put("numberOfFiles", results != null ? results.getNodeRefs().size() : 0);
if(isCalculationCompleted) if(isCalculationCompleted)
{ {
ruleAction.setParameterValue(RESULT, (Serializable) response); nodeAction.setParameterValue(RESULT, (Serializable) response);
actionsRecords.put(nodeAction.getId(),nodeAction);
SimpleCache<Serializable,Object> simpleCache = (SimpleCache<Serializable, Object>) serializedCache;
simpleCache.put(nodeAction.getId(),nodeAction);
} }
} }

View File

@@ -514,4 +514,10 @@
<bean name="ldapInitialDirContextCache" factory-bean="cacheFactory" factory-method="createCache"> <bean name="ldapInitialDirContextCache" factory-bean="cacheFactory" factory-method="createCache">
<constructor-arg value="cache.ldapInitialDirContextCache"/> <constructor-arg value="cache.ldapInitialDirContextCache"/>
</bean> </bean>
<!-- The shared cache for Folder Node -->
<bean name="folderSizeSharedCache" factory-bean="cacheFactory" factory-method="createCache">
<constructor-arg value="cache.folderSizeSharedCache"/>
</bean>
</beans> </beans>

View File

@@ -710,3 +710,12 @@ cache.ldapInitialDirContextCache.backup-count=1
cache.ldapInitialDirContextCache.eviction-policy=NONE cache.ldapInitialDirContextCache.eviction-policy=NONE
cache.ldapInitialDirContextCache.merge-policy=com.hazelcast.spi.merge.LatestUpdateMergePolicy cache.ldapInitialDirContextCache.merge-policy=com.hazelcast.spi.merge.LatestUpdateMergePolicy
cache.ldapInitialDirContextCache.readBackupData=false cache.ldapInitialDirContextCache.readBackupData=false
cache.folderSizeSharedCache.maxItems=1000
cache.folderSizeSharedCache.timeToLiveSeconds=0
cache.folderSizeSharedCache.maxIdleSeconds=0
cache.folderSizeSharedCache.cluster.type=fully-distributed
cache.folderSizeSharedCache.backup-count=1
cache.folderSizeSharedCache.eviction-policy=NONE
cache.folderSizeSharedCache.merge-policy=com.hazelcast.spi.merge.LatestUpdateMergePolicy
cache.folderSizeSharedCache.readBackupData=false