mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
DM Usages/Quotas fixes - protect system/admin-maintained properties, make store(s) configurable
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@7500 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -24,7 +24,8 @@
|
|||||||
<import resource="classpath:alfresco/script-services-context.xml" />
|
<import resource="classpath:alfresco/script-services-context.xml" />
|
||||||
<import resource="classpath:alfresco/index-recovery-context.xml" />
|
<import resource="classpath:alfresco/index-recovery-context.xml" />
|
||||||
<import resource="classpath:alfresco/authority-services-context.xml" />
|
<import resource="classpath:alfresco/authority-services-context.xml" />
|
||||||
<import resource="classpath:alfresco/authentication-services-context.xml" />
|
<import resource="classpath:alfresco/authentication-services-context.xml" />
|
||||||
|
<import resource="classpath:alfresco/usage-services-context.xml" />
|
||||||
<import resource="classpath:alfresco/policy-context.xml" />
|
<import resource="classpath:alfresco/policy-context.xml" />
|
||||||
<import resource="classpath:alfresco/import-export-context.xml" />
|
<import resource="classpath:alfresco/import-export-context.xml" />
|
||||||
<import resource="classpath:alfresco/bootstrap-context.xml" />
|
<import resource="classpath:alfresco/bootstrap-context.xml" />
|
||||||
|
@@ -201,9 +201,11 @@
|
|||||||
<!-- system maintained values -->
|
<!-- system maintained values -->
|
||||||
<property name="cm:sizeCurrent">
|
<property name="cm:sizeCurrent">
|
||||||
<type>d:long</type>
|
<type>d:long</type>
|
||||||
|
<protected>true</protected>
|
||||||
</property>
|
</property>
|
||||||
<property name="cm:sizeQuota">
|
<property name="cm:sizeQuota">
|
||||||
<type>d:long</type>
|
<type>d:long</type>
|
||||||
|
<protected>true</protected>
|
||||||
</property>
|
</property>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
@@ -195,28 +195,6 @@
|
|||||||
<property name="threshold">
|
<property name="threshold">
|
||||||
<value>5000</value>
|
<value>5000</value>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="usageService" class="org.alfresco.repo.usage.UsageServiceImpl">
|
|
||||||
<property name="usageDeltaDao">
|
|
||||||
<ref bean="usageDeltaDao"/>
|
|
||||||
</property>
|
|
||||||
<property name="nodeDaoService">
|
|
||||||
<ref bean="nodeDaoService" />
|
|
||||||
</property>
|
|
||||||
<property name="tenantService">
|
|
||||||
<ref bean="tenantService"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="contentUsageImpl" class="org.alfresco.repo.usage.ContentUsageImpl" init-method="init">
|
|
||||||
<property name="personService" ref="personService"/>
|
|
||||||
<property name="nodeService" ref="nodeService"/>
|
|
||||||
<property name="policyComponent" ref="policyComponent"/>
|
|
||||||
<property name="usageService" ref="usageService"/>
|
|
||||||
<property name="enabled">
|
|
||||||
<value>${system.usages.enabled}</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
41
config/alfresco/usage-services-context.xml
Normal file
41
config/alfresco/usage-services-context.xml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||||
|
|
||||||
|
<!-- Beans pertinent to content usage / quota service -->
|
||||||
|
<beans>
|
||||||
|
|
||||||
|
<bean id="usageService" class="org.alfresco.repo.usage.UsageServiceImpl">
|
||||||
|
<property name="usageDeltaDao">
|
||||||
|
<ref bean="usageDeltaDao"/>
|
||||||
|
</property>
|
||||||
|
<property name="nodeDaoService">
|
||||||
|
<ref bean="nodeDaoService" />
|
||||||
|
</property>
|
||||||
|
<property name="tenantService">
|
||||||
|
<ref bean="tenantService"/>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="contentUsageImpl" class="org.alfresco.repo.usage.ContentUsageImpl" init-method="init">
|
||||||
|
<property name="personService" ref="personService"/>
|
||||||
|
<property name="nodeService" ref="nodeService"/>
|
||||||
|
<property name="policyComponent" ref="policyComponent"/>
|
||||||
|
<property name="usageService" ref="usageService"/>
|
||||||
|
<property name="enabled">
|
||||||
|
<value>${system.usages.enabled}</value>
|
||||||
|
</property>
|
||||||
|
<property name="stores">
|
||||||
|
<list>
|
||||||
|
<value>workspace://SpacesStore</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="usageQuotaProtector" class="org.alfresco.repo.usage.UsageQuotaProtector" init-method="init">
|
||||||
|
<property name="authorityService" ref="authorityService"/>
|
||||||
|
<property name="authenticationService" ref="authenticationService"/>
|
||||||
|
<property name="policyComponent" ref="policyComponent"/>
|
||||||
|
<property name="contentUsageService" ref="ContentUsageService"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
@@ -25,6 +25,7 @@
|
|||||||
package org.alfresco.repo.usage;
|
package org.alfresco.repo.usage;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
@@ -35,7 +36,6 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|||||||
import org.alfresco.service.cmr.repository.ContentData;
|
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.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.cmr.usage.ContentQuotaException;
|
import org.alfresco.service.cmr.usage.ContentQuotaException;
|
||||||
import org.alfresco.service.cmr.usage.ContentUsageService;
|
import org.alfresco.service.cmr.usage.ContentUsageService;
|
||||||
@@ -64,8 +64,7 @@ public class ContentUsageImpl implements ContentUsageService,
|
|||||||
|
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
|
||||||
public static final StoreRef SPACES_STOREREF = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
|
private List<String> stores;
|
||||||
|
|
||||||
|
|
||||||
public void setNodeService(NodeService nodeService)
|
public void setNodeService(NodeService nodeService)
|
||||||
{
|
{
|
||||||
@@ -91,7 +90,16 @@ public class ContentUsageImpl implements ContentUsageService,
|
|||||||
{
|
{
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStores(List<String> stores)
|
||||||
|
{
|
||||||
|
this.stores = stores;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getStores()
|
||||||
|
{
|
||||||
|
return this.stores;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The initialise method
|
* The initialise method
|
||||||
@@ -129,7 +137,7 @@ public class ContentUsageImpl implements ContentUsageService,
|
|||||||
public void onCreateNode(ChildAssociationRef childAssocRef)
|
public void onCreateNode(ChildAssociationRef childAssocRef)
|
||||||
{
|
{
|
||||||
NodeRef nodeRef = childAssocRef.getChildRef();
|
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||||
if (nodeRef.getStoreRef().equals(SPACES_STOREREF))
|
if (stores.contains(nodeRef.getStoreRef().toString()))
|
||||||
{
|
{
|
||||||
// Get content size
|
// Get content size
|
||||||
|
|
||||||
@@ -165,7 +173,7 @@ public class ContentUsageImpl implements ContentUsageService,
|
|||||||
Map<QName, Serializable> before,
|
Map<QName, Serializable> before,
|
||||||
Map<QName, Serializable> after)
|
Map<QName, Serializable> after)
|
||||||
{
|
{
|
||||||
if (nodeRef.getStoreRef().equals(SPACES_STOREREF))
|
if (stores.contains(nodeRef.getStoreRef().toString()))
|
||||||
{
|
{
|
||||||
// Check for change in content size
|
// Check for change in content size
|
||||||
|
|
||||||
@@ -258,7 +266,7 @@ public class ContentUsageImpl implements ContentUsageService,
|
|||||||
*/
|
*/
|
||||||
public void beforeDeleteNode(NodeRef nodeRef)
|
public void beforeDeleteNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
if (nodeRef.getStoreRef().equals(SPACES_STOREREF))
|
if (stores.contains(nodeRef.getStoreRef().toString()))
|
||||||
{
|
{
|
||||||
// TODO use data dictionary to get content property
|
// TODO use data dictionary to get content property
|
||||||
ContentData contentData = (ContentData)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
ContentData contentData = (ContentData)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
||||||
|
118
source/java/org/alfresco/repo/usage/UsageQuotaProtector.java
Normal file
118
source/java/org/alfresco/repo/usage/UsageQuotaProtector.java
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.usage;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.node.NodeServicePolicies;
|
||||||
|
import org.alfresco.repo.policy.JavaBehaviour;
|
||||||
|
import org.alfresco.repo.policy.PolicyComponent;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
|
import org.alfresco.service.cmr.usage.ContentUsageService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements policies/behaviour for protecting system/admin-maintained person properties
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class UsageQuotaProtector implements NodeServicePolicies.OnUpdatePropertiesPolicy
|
||||||
|
{
|
||||||
|
private AuthorityService authorityService;
|
||||||
|
private AuthenticationService authenticationService;
|
||||||
|
private PolicyComponent policyComponent;
|
||||||
|
private ContentUsageService contentUsageService;
|
||||||
|
|
||||||
|
public void setAuthorityService(AuthorityService authorityService)
|
||||||
|
{
|
||||||
|
this.authorityService = authorityService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticationService(AuthenticationService authenticationService)
|
||||||
|
{
|
||||||
|
this.authenticationService = authenticationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentUsageService(ContentUsageService contentUsageService)
|
||||||
|
{
|
||||||
|
this.contentUsageService = contentUsageService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||||
|
{
|
||||||
|
this.policyComponent = policyComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The initialise method
|
||||||
|
*/
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
if (contentUsageService.getEnabled())
|
||||||
|
{
|
||||||
|
// Register interest in the onUpdateProperties policy
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||||
|
ContentModel.TYPE_PERSON,
|
||||||
|
new JavaBehaviour(this, "onUpdateProperties"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after a node's properties have been changed.
|
||||||
|
*
|
||||||
|
* @param nodeRef reference to the updated node
|
||||||
|
* @param before the node's properties before the change
|
||||||
|
* @param after the node's properties after the change
|
||||||
|
*/
|
||||||
|
public void onUpdateProperties(
|
||||||
|
NodeRef nodeRef,
|
||||||
|
Map<QName, Serializable> before,
|
||||||
|
Map<QName, Serializable> after)
|
||||||
|
{
|
||||||
|
Long sizeCurrentBefore = (Long)before.get(ContentModel.PROP_SIZE_CURRENT);
|
||||||
|
Long sizeCurrentAfter = (Long)after.get(ContentModel.PROP_SIZE_CURRENT);
|
||||||
|
|
||||||
|
Long sizeQuotaBefore = (Long)before.get(ContentModel.PROP_SIZE_QUOTA);
|
||||||
|
Long sizeQuotaAfter = (Long)after.get(ContentModel.PROP_SIZE_QUOTA);
|
||||||
|
|
||||||
|
// Check for change in sizeCurrent
|
||||||
|
if ((sizeCurrentBefore != sizeCurrentAfter) && (! (authorityService.hasAdminAuthority() || authenticationService.isCurrentUserTheSystemUser())))
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Update failed: protected property 'sizeCurrent'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for change in sizeQuota
|
||||||
|
if ((sizeQuotaBefore != sizeQuotaAfter) && (! authorityService.hasAdminAuthority()))
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Update failed: protected property 'sizeQuota'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -26,11 +26,13 @@ package org.alfresco.repo.usage;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.domain.Node;
|
import org.alfresco.repo.domain.Node;
|
||||||
import org.alfresco.repo.node.db.NodeDaoService;
|
import org.alfresco.repo.node.db.NodeDaoService;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
import org.alfresco.repo.transaction.TransactionServiceImpl;
|
import org.alfresco.repo.transaction.TransactionServiceImpl;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
@@ -201,52 +203,56 @@ public class UserUsageTrackingComponent
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Collapse usage deltas (if a person has initial usage set)
|
// Collapse usage deltas (if a person has initial usage set)
|
||||||
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
final RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
||||||
|
|
||||||
// wrap to make the request in a transaction
|
// wrap to make the request in a transaction and run as System user
|
||||||
RetryingTransactionCallback<Object> collapseUsages = new RetryingTransactionCallback<Object>()
|
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||||
{
|
{
|
||||||
public Object execute() throws Throwable
|
public Object doWork() throws Exception
|
||||||
{
|
{
|
||||||
// Get distinct candidates
|
return txnHelper.doInTransaction(new RetryingTransactionCallback<Object>()
|
||||||
Set<NodeRef> usageNodeRefs = usageService.getUsageDeltaNodes();
|
{
|
||||||
|
public Object execute() throws Throwable
|
||||||
for(NodeRef usageNodeRef : usageNodeRefs)
|
|
||||||
{
|
|
||||||
QName nodeType = nodeService.getType(usageNodeRef);
|
|
||||||
|
|
||||||
if (nodeType.equals(ContentModel.TYPE_PERSON))
|
|
||||||
{
|
{
|
||||||
NodeRef personNodeRef = usageNodeRef;
|
// Get distinct candidates
|
||||||
String userName = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME);
|
Set<NodeRef> usageNodeRefs = usageService.getUsageDeltaNodes();
|
||||||
|
|
||||||
long currentUsage = contentUsageImpl.getUserStoredUsage(personNodeRef);
|
for(NodeRef usageNodeRef : usageNodeRefs)
|
||||||
if (currentUsage != -1)
|
{
|
||||||
{
|
QName nodeType = nodeService.getType(usageNodeRef);
|
||||||
// collapse the usage deltas
|
|
||||||
currentUsage = contentUsageImpl.getUserUsage(userName);
|
|
||||||
usageService.deleteDeltas(personNodeRef);
|
|
||||||
contentUsageImpl.setUserStoredUsage(personNodeRef, currentUsage);
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (nodeType.equals(ContentModel.TYPE_PERSON))
|
||||||
{
|
{
|
||||||
logger.debug("Collapsed usage: username=" + userName + ", usage=" + currentUsage);
|
NodeRef personNodeRef = usageNodeRef;
|
||||||
|
String userName = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME);
|
||||||
|
|
||||||
|
long currentUsage = contentUsageImpl.getUserStoredUsage(personNodeRef);
|
||||||
|
if (currentUsage != -1)
|
||||||
|
{
|
||||||
|
// collapse the usage deltas
|
||||||
|
currentUsage = contentUsageImpl.getUserUsage(userName);
|
||||||
|
usageService.deleteDeltas(personNodeRef);
|
||||||
|
contentUsageImpl.setUserStoredUsage(personNodeRef, currentUsage);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Collapsed usage: username=" + userName + ", usage=" + currentUsage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logger.isWarnEnabled())
|
||||||
|
{
|
||||||
|
logger.warn("Initial usage for user has not yet been calculated: " + userName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
return null;
|
||||||
{
|
|
||||||
if (logger.isWarnEnabled())
|
|
||||||
{
|
|
||||||
logger.warn("Initial usage for user has not yet been calculated: " + userName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
};
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
|
||||||
txnHelper.doInTransaction(collapseUsages, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,45 +271,50 @@ public class UserUsageTrackingComponent
|
|||||||
*/
|
*/
|
||||||
public void recalculateUsage(final String userName)
|
public void recalculateUsage(final String userName)
|
||||||
{
|
{
|
||||||
final StoreRef storeRef = ContentUsageImpl.SPACES_STOREREF;
|
final RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
||||||
|
|
||||||
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
|
||||||
|
|
||||||
// wrap to make the request in a transaction
|
// wrap to make the request in a transaction
|
||||||
RetryingTransactionCallback<Long> calculatePersonCurrentUsage = new RetryingTransactionCallback<Long>()
|
RetryingTransactionCallback<Long> calculatePersonCurrentUsage = new RetryingTransactionCallback<Long>()
|
||||||
{
|
{
|
||||||
public Long execute() throws Throwable
|
public Long execute() throws Throwable
|
||||||
{
|
{
|
||||||
// get nodes for which user is owner
|
List<String> stores = contentUsageImpl.getStores();
|
||||||
Collection<Node> ownerNodes = nodeDaoService.getNodesWithPropertyStringValueForStore(storeRef, ContentModel.PROP_OWNER, userName);
|
|
||||||
|
|
||||||
long totalUsage = 0;
|
long totalUsage = 0;
|
||||||
for (Node ownerNode : ownerNodes)
|
|
||||||
|
for (String store : stores)
|
||||||
{
|
{
|
||||||
if (ownerNode.getTypeQName().equals(ContentModel.TYPE_CONTENT))
|
StoreRef storeRef = new StoreRef(store);
|
||||||
|
|
||||||
|
// get nodes for which user is owner
|
||||||
|
Collection<Node> ownerNodes = nodeDaoService.getNodesWithPropertyStringValueForStore(storeRef, ContentModel.PROP_OWNER, userName);
|
||||||
|
|
||||||
|
for (Node ownerNode : ownerNodes)
|
||||||
{
|
{
|
||||||
ContentData contentData = ContentData.createContentProperty(ownerNode.getProperties().get(ContentModel.PROP_CONTENT).getStringValue());
|
if (ownerNode.getTypeQName().equals(ContentModel.TYPE_CONTENT))
|
||||||
totalUsage = totalUsage + contentData.getSize();
|
{
|
||||||
|
ContentData contentData = ContentData.createContentProperty(ownerNode.getProperties().get(ContentModel.PROP_CONTENT).getStringValue());
|
||||||
|
totalUsage = totalUsage + contentData.getSize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// get nodes for which user is creator, and then filter out those that have an owner
|
||||||
// get nodes for which user is creator, and then filter out those that have an owner
|
Collection<Node> creatorNodes = nodeDaoService.getNodesWithPropertyStringValueForStore(storeRef, ContentModel.PROP_CREATOR, userName);
|
||||||
Collection<Node> creatorNodes = nodeDaoService.getNodesWithPropertyStringValueForStore(storeRef, ContentModel.PROP_CREATOR, userName);
|
|
||||||
|
for (Node creatorNode : creatorNodes)
|
||||||
for (Node creatorNode : creatorNodes)
|
|
||||||
{
|
|
||||||
if (creatorNode.getTypeQName().equals(ContentModel.TYPE_CONTENT) &&
|
|
||||||
creatorNode.getProperties().get(ContentModel.PROP_OWNER) == null)
|
|
||||||
{
|
{
|
||||||
ContentData contentData = ContentData.createContentProperty(creatorNode.getProperties().get(ContentModel.PROP_CONTENT).getStringValue());
|
if (creatorNode.getTypeQName().equals(ContentModel.TYPE_CONTENT) &&
|
||||||
totalUsage = totalUsage + contentData.getSize();
|
creatorNode.getProperties().get(ContentModel.PROP_OWNER) == null)
|
||||||
|
{
|
||||||
|
ContentData contentData = ContentData.createContentProperty(creatorNode.getProperties().get(ContentModel.PROP_CONTENT).getStringValue());
|
||||||
|
totalUsage = totalUsage + contentData.getSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
long quotaSize = contentUsageImpl.getUserQuota(userName);
|
||||||
|
logger.debug("Recalc usage ("+ userName+") totalUsage="+totalUsage+", quota="+quotaSize);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
long quotaSize = contentUsageImpl.getUserQuota(userName);
|
|
||||||
logger.debug("Recalc usage ("+ userName+") totalUsage="+totalUsage+", quota="+quotaSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalUsage;
|
return totalUsage;
|
||||||
@@ -312,17 +323,22 @@ public class UserUsageTrackingComponent
|
|||||||
// execute in READ-ONLY txn
|
// execute in READ-ONLY txn
|
||||||
final Long currentUsage = txnHelper.doInTransaction(calculatePersonCurrentUsage, true);
|
final Long currentUsage = txnHelper.doInTransaction(calculatePersonCurrentUsage, true);
|
||||||
|
|
||||||
// wrap to make the request in a transaction
|
// wrap to make the request in a transaction and run as System user
|
||||||
RetryingTransactionCallback<Object> setUserCurrentUsage = new RetryingTransactionCallback<Object>()
|
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||||
{
|
{
|
||||||
public Object execute() throws Throwable
|
public Object doWork() throws Exception
|
||||||
{
|
{
|
||||||
NodeRef personNodeRef = personService.getPerson(userName);
|
return txnHelper.doInTransaction(new RetryingTransactionCallback<Object>()
|
||||||
contentUsageImpl.setUserStoredUsage(personNodeRef, currentUsage);
|
{
|
||||||
usageService.deleteDeltas(personNodeRef);
|
public Object execute() throws Throwable
|
||||||
return null;
|
{
|
||||||
|
NodeRef personNodeRef = personService.getPerson(userName);
|
||||||
|
contentUsageImpl.setUserStoredUsage(personNodeRef, currentUsage);
|
||||||
|
usageService.deleteDeltas(personNodeRef);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
txnHelper.doInTransaction(setUserCurrentUsage, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user