mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-08 14:51:49 +00:00
[feature/MNT-24127] EndpointToCalculateFolderSize
This commit is contained in:
@@ -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>
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
@@ -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>
|
||||||
|
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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>
|
||||||
|
@@ -709,4 +709,13 @@ cache.ldapInitialDirContextCache.cluster.type=fully-distributed
|
|||||||
cache.ldapInitialDirContextCache.backup-count=1
|
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
|
Reference in New Issue
Block a user