mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-01 14:41:46 +00:00
[feature/MNT-24127-EndpointToCalculateFolderSize] Added Endpoint to calculate folder size
This commit is contained in:
@@ -45,6 +45,18 @@ public class FolderSizeImpl {
|
|||||||
private static final String IN_PROGRESS = "IN-PROGRESS";
|
private static final String IN_PROGRESS = "IN-PROGRESS";
|
||||||
|
|
||||||
public Map<String, Object> executingAsynchronousFolderAction(final NodeRef nodeRef, final int maxItems, final Map<String, Object> result, final SimpleCache<Serializable, Object> simpleCache)
|
public Map<String, Object> executingAsynchronousFolderAction(final NodeRef nodeRef, final int maxItems, final Map<String, Object> result, final SimpleCache<Serializable, Object> simpleCache)
|
||||||
|
{
|
||||||
|
if(simpleCache.get(nodeRef.getId()) == null)
|
||||||
|
{
|
||||||
|
executeAction(nodeRef, maxItems, simpleCache);
|
||||||
|
}
|
||||||
|
LOG.debug("Executing NodeSizeActionExecuter from executingAsynchronousFolderAction method");
|
||||||
|
|
||||||
|
result.putIfAbsent("nodeId",nodeRef.getId());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void executeAction(NodeRef nodeRef, int maxItems, SimpleCache<Serializable, Object> simpleCache)
|
||||||
{
|
{
|
||||||
Action folderSizeAction = actionService.createAction(NodeSizeActionExecuter.NAME);
|
Action folderSizeAction = actionService.createAction(NodeSizeActionExecuter.NAME);
|
||||||
folderSizeAction.setTrackStatus(true);
|
folderSizeAction.setTrackStatus(true);
|
||||||
@@ -52,10 +64,5 @@ public class FolderSizeImpl {
|
|||||||
folderSizeAction.setParameterValue(NodeSizeActionExecuter.PAGE_SIZE, maxItems);
|
folderSizeAction.setParameterValue(NodeSizeActionExecuter.PAGE_SIZE, maxItems);
|
||||||
simpleCache.put(nodeRef.getId(),IN_PROGRESS);
|
simpleCache.put(nodeRef.getId(),IN_PROGRESS);
|
||||||
actionService.executeAction(folderSizeAction, nodeRef, false, true);
|
actionService.executeAction(folderSizeAction, nodeRef, false, true);
|
||||||
|
|
||||||
LOG.debug("Executing NodeSizeActionExecuter from executingAsynchronousFolderAction method");
|
|
||||||
|
|
||||||
result.putIfAbsent("executionId",folderSizeAction.getId());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -282,7 +282,7 @@ public class ResourceWebScriptGet extends AbstractResourceWebScript implements P
|
|||||||
if (StringUtils.isNotBlank(params.getEntityId()))
|
if (StringUtils.isNotBlank(params.getEntityId()))
|
||||||
{
|
{
|
||||||
if (EntityResourceAction.RetrieveFolderSize.class.isAssignableFrom(resource.getResource().getClass())
|
if (EntityResourceAction.RetrieveFolderSize.class.isAssignableFrom(resource.getResource().getClass())
|
||||||
&& (GET_FOLDERSIZE.equals(resource.getMetaData().getUniqueId()) || params.getBinaryProperty().equals("get-folder-size")))
|
&& (GET_FOLDERSIZE.equals(resource.getMetaData().getUniqueId())))
|
||||||
{
|
{
|
||||||
if (resource.getMetaData().isDeleted(EntityResourceAction.RetrieveFolderSize.class))
|
if (resource.getMetaData().isDeleted(EntityResourceAction.RetrieveFolderSize.class))
|
||||||
{
|
{
|
||||||
|
@@ -100,9 +100,9 @@ public class NodeFolderSizeApiTest extends AbstractBaseApiTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test case for POST/calculateSize, which calculates Folder Size.
|
* Test case for POST/calculate-folder-size, which calculates Folder Size.
|
||||||
* <p>POST:</p>
|
* <p>POST:</p>
|
||||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/nodes/<nodeId>/calculateSize}
|
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/nodes/<nodeId>/calculate-folder-size}
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAPostCalculateFolderSize() throws Exception {
|
public void testAPostCalculateFolderSize() throws Exception {
|
||||||
@@ -129,9 +129,9 @@ public class NodeFolderSizeApiTest extends AbstractBaseApiTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test case for GET/calculateSize, to retrieve FolderSize.
|
* Test case for GET/get-folder-size, to retrieve FolderSize.
|
||||||
* <p>GET:</p>
|
* <p>GET:</p>
|
||||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/nodes/<nodeId>/calculateSize}
|
* {@literal <host>:<port>/alfresco/api/-default-/public/alfresco/versions/1/nodes/<nodeId>/get-folder-size}
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBGetCalculateFolderSize() throws Exception
|
public void testBGetCalculateFolderSize() throws Exception
|
||||||
|
@@ -305,6 +305,7 @@ public class PublicApiHttpClient
|
|||||||
{
|
{
|
||||||
RestApiEndpoint endpoint = new RestApiEndpoint(c, rq.getNetworkId(), entityId, relationshipEntityId, params);
|
RestApiEndpoint endpoint = new RestApiEndpoint(c, rq.getNetworkId(), entityId, relationshipEntityId, params);
|
||||||
String url = endpoint.getUrl();
|
String url = endpoint.getUrl();
|
||||||
|
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&& "+url+" :: "+entityId);
|
||||||
|
|
||||||
GetMethod req = new GetMethod(url);
|
GetMethod req = new GetMethod(url);
|
||||||
return submitRequest(req, rq);
|
return submitRequest(req, rq);
|
||||||
@@ -762,6 +763,7 @@ public class PublicApiHttpClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
addParams(sb, params);
|
addParams(sb, params);
|
||||||
|
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&& 2 "+sb.toString());
|
||||||
|
|
||||||
this.url = sb.toString();
|
this.url = sb.toString();
|
||||||
}
|
}
|
||||||
|
@@ -25,14 +25,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.action.executer;
|
package org.alfresco.repo.action.executer;
|
||||||
|
|
||||||
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.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.NodeRef;
|
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.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.cmr.search.ResultSet;
|
import org.alfresco.service.cmr.search.ResultSet;
|
||||||
import org.alfresco.service.cmr.search.SearchParameters;
|
import org.alfresco.service.cmr.search.SearchParameters;
|
||||||
@@ -49,7 +46,6 @@ import java.time.format.DateTimeFormatter;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NodeSizeActionExecuter
|
* NodeSizeActionExecuter
|
||||||
@@ -58,34 +54,20 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
|
|
||||||
public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
|
public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(NodeSizeActionExecuter.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action constants
|
* Action constants
|
||||||
*/
|
*/
|
||||||
public static final String NAME = "folder-size";
|
public static final String NAME = "folder-size";
|
||||||
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 ERROR = "exception";
|
public static final String ERROR = "exception";
|
||||||
public static final String FIELD_FACET = "content.size";
|
public static final String FIELD_FACET = "content.size";
|
||||||
|
|
||||||
private NodeService nodeService;
|
|
||||||
private SearchService searchService;
|
private SearchService searchService;
|
||||||
private SimpleCache<Serializable,Object> simpleCache;
|
private SimpleCache<Serializable,Object> simpleCache;
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger
|
|
||||||
*/
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(NodeSizeActionExecuter.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the node service
|
|
||||||
*
|
|
||||||
* @param nodeService the node service
|
|
||||||
*/
|
|
||||||
public void setNodeService(NodeService nodeService)
|
|
||||||
{
|
|
||||||
this.nodeService = nodeService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the search service
|
* Set the search service
|
||||||
*
|
*
|
||||||
@@ -128,11 +110,39 @@ public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
NodeRef nodeRef = actionedUponNodeRef;
|
NodeRef nodeRef = actionedUponNodeRef;
|
||||||
long totalSize = 0;
|
|
||||||
long totalSizeFromFacet;
|
long totalSizeFromFacet;
|
||||||
ResultSet results;
|
ResultSet results;
|
||||||
boolean isCalculationCompleted = false;
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// executing Alfresco FTS facet query.
|
||||||
|
results = facetQuery(nodeRef);
|
||||||
|
List<Pair<String, Integer>> fieldData = results.getFieldFacet(FIELD_FACET);
|
||||||
|
totalSizeFromFacet = fieldData.stream()
|
||||||
|
.filter(pairData -> pairData.getSecond() > 0)
|
||||||
|
.mapToLong(pairData -> Long.valueOf(pairData.getFirst()) * pairData.getSecond())
|
||||||
|
.sum();
|
||||||
|
}
|
||||||
|
catch (RuntimeException ex)
|
||||||
|
{
|
||||||
|
LOG.error("Exception occurred in NodeSizeActionExecutor:results {}", ex.getMessage());
|
||||||
|
nodeAction.setParameterValue(ERROR, ex.getMessage());
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug(" Calculating size of Folder Node - NodeSizeActionExecutor:executeImpl ");
|
||||||
|
final LocalDateTime eventTimestamp = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ss");
|
||||||
|
String formattedTimestamp = eventTimestamp.format(formatter);
|
||||||
|
response.put("nodeId", nodeRef.getId());
|
||||||
|
response.put("size", totalSizeFromFacet);
|
||||||
|
response.put("calculatedAt", formattedTimestamp);
|
||||||
|
response.put("numberOfFiles", results != null ? results.getNodeRefs().size() : 0);
|
||||||
|
simpleCache.put(nodeRef.getId(),response);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ResultSet facetQuery(NodeRef nodeRef)
|
||||||
|
{
|
||||||
StringBuilder aftsQuery = new StringBuilder();
|
StringBuilder aftsQuery = new StringBuilder();
|
||||||
aftsQuery.append("ANCESTOR:\"").append(nodeRef).append("\" AND TYPE:content");
|
aftsQuery.append("ANCESTOR:\"").append(nodeRef).append("\" AND TYPE:content");
|
||||||
String query = aftsQuery.toString();
|
String query = aftsQuery.toString();
|
||||||
@@ -147,77 +157,7 @@ public class NodeSizeActionExecuter extends ActionExecuterAbstractBase
|
|||||||
searchParameters.addFacetQuery("content.size:[1048576 TO 16777216]\", \"label\": \"large\",\"group\":\"Size\"");
|
searchParameters.addFacetQuery("content.size:[1048576 TO 16777216]\", \"label\": \"large\",\"group\":\"Size\"");
|
||||||
final SearchParameters.FieldFacet ff = new SearchParameters.FieldFacet(FIELD_FACET);
|
final SearchParameters.FieldFacet ff = new SearchParameters.FieldFacet(FIELD_FACET);
|
||||||
searchParameters.addFieldFacet(ff);
|
searchParameters.addFieldFacet(ff);
|
||||||
|
return searchService.query(searchParameters);
|
||||||
try
|
|
||||||
{
|
|
||||||
// executing Alfresco FTS query.
|
|
||||||
results = searchService.query(searchParameters);
|
|
||||||
List<Pair<String, Integer>> fieldData = results.getFieldFacet(FIELD_FACET);
|
|
||||||
totalSizeFromFacet = fieldData.stream()
|
|
||||||
.filter(pairData -> pairData.getSecond() > 0)
|
|
||||||
.mapToLong(pairData -> Long.valueOf(pairData.getFirst()) * pairData.getSecond())
|
|
||||||
.sum();
|
|
||||||
|
|
||||||
int skipCount = 0;
|
|
||||||
int totalItems;
|
|
||||||
totalItems = Math.min(results.getNodeRefs().size(), maxItems);
|
|
||||||
|
|
||||||
while (!isCalculationCompleted)
|
|
||||||
{
|
|
||||||
List<NodeRef> nodeRefs = results.getNodeRefs().subList(skipCount, totalItems);
|
|
||||||
// Using AtomicLong to accumulate the total size.
|
|
||||||
AtomicLong resultSize = new AtomicLong(0);
|
|
||||||
nodeRefs.parallelStream().forEach(id -> {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ContentData contentData = (ContentData) nodeService.getProperty(id, ContentModel.PROP_CONTENT);
|
|
||||||
if (contentData != null)
|
|
||||||
{
|
|
||||||
resultSize.addAndGet(contentData.getSize());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
resultSize.addAndGet(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
totalSize+=resultSize.longValue();
|
|
||||||
|
|
||||||
if (results.getNodeRefs().size() <= totalItems || results.getNodeRefs().size() <= maxItems)
|
|
||||||
{
|
|
||||||
isCalculationCompleted = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
skipCount += maxItems;
|
|
||||||
int remainingItems = results.getNodeRefs().size() - totalItems;
|
|
||||||
totalItems += Math.min(remainingItems, maxItems);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (RuntimeException ex)
|
|
||||||
{
|
|
||||||
LOG.error("Exception occurred in NodeSizeActionExecutor:results {}", ex.getMessage());
|
|
||||||
nodeAction.setParameterValue(ERROR, ex.getMessage());
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.debug(" Calculating size of Folder Node - NodeSizeActionExecutor:executeImpl ");
|
|
||||||
final LocalDateTime eventTimestamp = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
|
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ss");
|
|
||||||
String formattedTimestamp = eventTimestamp.format(formatter);
|
|
||||||
response.put("id", nodeRef.getId());
|
|
||||||
response.put("size", totalSize);
|
|
||||||
response.put("sizeFromFacet", totalSizeFromFacet);
|
|
||||||
response.put("calculatedAt", formattedTimestamp);
|
|
||||||
response.put("numberOfFiles", results != null ? results.getNodeRefs().size() : 0);
|
|
||||||
|
|
||||||
if(isCalculationCompleted)
|
|
||||||
{
|
|
||||||
nodeAction.setParameterValue(RESULT, (Serializable) response);
|
|
||||||
simpleCache.put(nodeRef.getId(),response);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -791,7 +791,6 @@
|
|||||||
|
|
||||||
<bean id="folder-size" class="org.alfresco.repo.action.executer.NodeSizeActionExecuter" parent="action-executer">
|
<bean id="folder-size" class="org.alfresco.repo.action.executer.NodeSizeActionExecuter" parent="action-executer">
|
||||||
<property name="searchService" ref="searchService"/>
|
<property name="searchService" ref="searchService"/>
|
||||||
<property name="nodeService" ref="nodeService"/>
|
|
||||||
<property name="simpleCache" ref="folderSizeSharedCache" />
|
<property name="simpleCache" ref="folderSizeSharedCache" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
@@ -108,7 +108,7 @@ public class NodeSizeActionExecuterTest extends BaseSpringTest
|
|||||||
ActionImpl action = new ActionImpl(null, ID, NodeSizeActionExecuter.NAME, null);
|
ActionImpl action = new ActionImpl(null, ID, NodeSizeActionExecuter.NAME, null);
|
||||||
action.setParameterValue(NodeSizeActionExecuter.PAGE_SIZE, maxItems);
|
action.setParameterValue(NodeSizeActionExecuter.PAGE_SIZE, maxItems);
|
||||||
this.executer.executeImpl(action, this.nodeRef);
|
this.executer.executeImpl(action, this.nodeRef);
|
||||||
Object resultAction = action.getParameterValue(NodeSizeActionExecuter.RESULT);
|
Object resultAction = simpleCache.get(this.nodeRef.getId());
|
||||||
Map<String, Object> mapResult = (Map<String, Object>)resultAction;
|
Map<String, Object> mapResult = (Map<String, Object>)resultAction;
|
||||||
assertTrue(mapResult != null);
|
assertTrue(mapResult != null);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user