mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Activity Service - improve feed cleaner test and fix ALFCOM-2838
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14183 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -3,15 +3,22 @@
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="activityService" class="org.alfresco.repo.activities.ActivityServiceImpl">
|
||||
<!-- Note: ActivityService / FeedGenerator -> SiteService -> ActivityPostService -->
|
||||
|
||||
<bean id="activityPostService" class="org.alfresco.repo.activities.ActivityPostServiceImpl">
|
||||
<property name="postDAO" ref="postDAO"/>
|
||||
<property name="tenantService" ref="tenantService"/>
|
||||
<property name="userNamesAreCaseSensitive" value="${user.name.caseSensitive}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="activityService" class="org.alfresco.repo.activities.ActivityServiceImpl">
|
||||
<property name="feedDAO" ref="feedDAO"/>
|
||||
<property name="feedControlDAO" ref="feedControlDAO"/>
|
||||
<property name="authorityService" ref="AuthorityService"/>
|
||||
<property name="tenantService" ref="tenantService"/>
|
||||
<property name="siteService" ref="siteService"/>
|
||||
<property name="activityPostService" ref="activityPostService"/>
|
||||
<property name="userNamesAreCaseSensitive" value="${user.name.caseSensitive}"/>
|
||||
<property name="feedGenerator" ref="feedGenerator"/>
|
||||
<property name="maxFeedItems" value="${activities.feed.max.size}"/>
|
||||
</bean>
|
||||
|
||||
@@ -50,6 +57,7 @@
|
||||
<property name="repoEndPoint" value="${repo.remote.endpoint.url}"/>
|
||||
<property name="userNamesAreCaseSensitive" value="${user.name.caseSensitive}"/>
|
||||
<property name="maxItemsPerCycle" value="100"/>
|
||||
<property name="activityPostServiceImpl" ref="activityPostService"/>
|
||||
</bean>
|
||||
|
||||
|
||||
|
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 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.activities;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.domain.activities.ActivityPostDAO;
|
||||
import org.alfresco.repo.domain.activities.ActivityPostEntity;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.cmr.activities.ActivityPostService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Activity Post Service Implementation
|
||||
*
|
||||
* @author janv
|
||||
*/
|
||||
public class ActivityPostServiceImpl implements ActivityPostService
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(ActivityServiceImpl.class);
|
||||
|
||||
private static final int MAX_LEN_USER_ID = 255; // needs to match schema: feed_user_id, post_user_id
|
||||
private static final int MAX_LEN_SITE_ID = 255; // needs to match schema: site_network
|
||||
private static final int MAX_LEN_ACTIVITY_TYPE = 255; // needs to match schema: activity_type
|
||||
private static final int MAX_LEN_ACTIVITY_DATA = 4000; // needs to match schema: activity_data
|
||||
private static final int MAX_LEN_APP_TOOL_ID = 36; // needs to match schema: app_tool
|
||||
|
||||
private ActivityPostDAO postDAO;
|
||||
private TenantService tenantService;
|
||||
private int estGridSize = 1;
|
||||
|
||||
private boolean userNamesAreCaseSensitive = false;
|
||||
|
||||
public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive)
|
||||
{
|
||||
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive;
|
||||
}
|
||||
|
||||
public void setPostDAO(ActivityPostDAO postDAO)
|
||||
{
|
||||
this.postDAO = postDAO;
|
||||
}
|
||||
|
||||
public void setTenantService(TenantService tenantService)
|
||||
{
|
||||
this.tenantService = tenantService;
|
||||
}
|
||||
|
||||
public void setEstimatedGridSize(int estGridSize)
|
||||
{
|
||||
this.estGridSize = estGridSize;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.activities.ActivityService#postActivity(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, String activityData)
|
||||
{
|
||||
postActivity(activityType, siteId, appTool, activityData, ActivityPostEntity.STATUS.PENDING);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.activities.ActivityService#postActivity(java.lang.String, java.lang.String, java.lang.String, org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("{").append("\"nodeRef\":\"").append(nodeRef.toString()).append("\"").append("}");
|
||||
|
||||
postActivity(activityType, siteId, appTool, sb.toString(), ActivityPostEntity.STATUS.PENDING);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.activities.ActivityService#postActivity(java.lang.String, java.lang.String, java.lang.String, org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String name)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("{").append("\"nodeRef\":\"").append(nodeRef.toString()).append("\"").append(",")
|
||||
.append("\"name\":\"").append(name).append("\"")
|
||||
.append("}");
|
||||
|
||||
postActivity(activityType, siteId, appTool, sb.toString(), ActivityPostEntity.STATUS.PENDING);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.activities.ActivityService#postActivity(java.lang.String, java.lang.String, java.lang.String, org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.service.namespace.QName, org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String name, QName typeQName, NodeRef parentNodeRef)
|
||||
{
|
||||
// primarily for delete node activities - eg. delete document, delete folder
|
||||
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
ParameterCheck.mandatory("typeQName", typeQName);
|
||||
ParameterCheck.mandatory("parentNodeRef", parentNodeRef);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("{").append("\"nodeRef\":\"").append(nodeRef.toString()).append("\"").append(",")
|
||||
.append("\"name\":\"").append(name).append("\"").append(",")
|
||||
.append("\"typeQName\":\"").append(typeQName.toPrefixString()).append("\"").append(",") // TODO toPrefixString does not return prefix ??!!
|
||||
.append("\"parentNodeRef\":\"").append(parentNodeRef.toString()).append("\"")
|
||||
.append("}");
|
||||
|
||||
postActivity(activityType, siteId, appTool, sb.toString(), ActivityPostEntity.STATUS.PENDING);
|
||||
}
|
||||
|
||||
private void postActivity(String activityType, String siteId, String appTool, String activityData, ActivityPostEntity.STATUS status)
|
||||
{
|
||||
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
|
||||
try
|
||||
{
|
||||
// optional - default to empty string
|
||||
if (siteId == null)
|
||||
{
|
||||
siteId = "";
|
||||
}
|
||||
else if (siteId.length() > MAX_LEN_SITE_ID)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid siteId - exceeds " + MAX_LEN_SITE_ID + " chars: " + siteId);
|
||||
}
|
||||
|
||||
// optional - default to empty string
|
||||
if (appTool == null)
|
||||
{
|
||||
appTool = "";
|
||||
}
|
||||
else if (appTool.length() > MAX_LEN_APP_TOOL_ID)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid app tool - exceeds " + MAX_LEN_APP_TOOL_ID + " chars: " + appTool);
|
||||
}
|
||||
|
||||
// required
|
||||
ParameterCheck.mandatoryString("activityType", activityType);
|
||||
|
||||
if (activityType.length() > MAX_LEN_ACTIVITY_TYPE)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid activity type - exceeds " + MAX_LEN_ACTIVITY_TYPE + " chars: " + activityType);
|
||||
}
|
||||
|
||||
// optional - default to empty string
|
||||
if (activityData == null)
|
||||
{
|
||||
activityData = "";
|
||||
}
|
||||
else if (activityType.length() > MAX_LEN_ACTIVITY_DATA)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid activity data - exceeds " + MAX_LEN_ACTIVITY_DATA + " chars: " + activityData);
|
||||
}
|
||||
|
||||
// required
|
||||
ParameterCheck.mandatoryString("currentUser", currentUser);
|
||||
|
||||
if (currentUser.length() > MAX_LEN_USER_ID)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid user - exceeds " + MAX_LEN_USER_ID + " chars: " + currentUser);
|
||||
}
|
||||
else if ((! currentUser.equals(AuthenticationUtil.SYSTEM_USER_NAME)) && (! userNamesAreCaseSensitive))
|
||||
{
|
||||
// user names are not case-sensitive
|
||||
currentUser = currentUser.toLowerCase();
|
||||
}
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
// log error and throw exception
|
||||
logger.error(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Date postDate = new Date();
|
||||
ActivityPostEntity activityPost = new ActivityPostEntity();
|
||||
activityPost.setUserId(currentUser);
|
||||
|
||||
activityPost.setSiteNetwork(tenantService.getName(siteId));
|
||||
|
||||
activityPost.setAppTool(appTool);
|
||||
activityPost.setActivityData(activityData);
|
||||
activityPost.setActivityType(activityType);
|
||||
activityPost.setPostDate(postDate);
|
||||
activityPost.setStatus(status.toString());
|
||||
activityPost.setLastModified(postDate);
|
||||
|
||||
// hash the userid to generate a job task node
|
||||
int nodeCount = estGridSize;
|
||||
int userHashCode = currentUser.hashCode();
|
||||
int nodeHash = (userHashCode % nodeCount) + 1;
|
||||
|
||||
activityPost.setJobTaskNode(nodeHash);
|
||||
|
||||
try
|
||||
{
|
||||
long postId = postDAO.insertPost(activityPost);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
activityPost.setId(postId);
|
||||
logger.debug("Posted: " + activityPost);
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to post activity: " + e, e);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to post activity: " + t, t);
|
||||
}
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
// log error, subsume exception (for post activity)
|
||||
logger.error(e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -26,20 +26,17 @@ package org.alfresco.repo.activities;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.activities.feed.FeedGenerator;
|
||||
import org.alfresco.repo.domain.activities.ActivityFeedDAO;
|
||||
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
|
||||
import org.alfresco.repo.domain.activities.ActivityPostDAO;
|
||||
import org.alfresco.repo.domain.activities.ActivityPostEntity;
|
||||
import org.alfresco.repo.domain.activities.FeedControlDAO;
|
||||
import org.alfresco.repo.domain.activities.FeedControlEntity;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.cmr.activities.ActivityPostService;
|
||||
import org.alfresco.service.cmr.activities.ActivityService;
|
||||
import org.alfresco.service.cmr.activities.FeedControl;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -61,20 +58,12 @@ public class ActivityServiceImpl implements ActivityService
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(ActivityServiceImpl.class);
|
||||
|
||||
private static final int MAX_LEN_USER_ID = 255; // needs to match schema: feed_user_id, post_user_id
|
||||
private static final int MAX_LEN_SITE_ID = 255; // needs to match schema: site_network
|
||||
private static final int MAX_LEN_ACTIVITY_TYPE = 255; // needs to match schema: activity_type
|
||||
private static final int MAX_LEN_ACTIVITY_DATA = 4000; // needs to match schema: activity_data
|
||||
private static final int MAX_LEN_APP_TOOL_ID = 36; // needs to match schema: app_tool
|
||||
|
||||
private ActivityPostDAO postDAO;
|
||||
private ActivityFeedDAO feedDAO;
|
||||
private FeedControlDAO feedControlDAO;
|
||||
private AuthorityService authorityService;
|
||||
private FeedGenerator feedGenerator;
|
||||
private SiteService siteService;
|
||||
|
||||
private TenantService tenantService;
|
||||
private SiteService siteService;
|
||||
private ActivityPostService activityPostService;
|
||||
|
||||
private int maxFeedItems = 100;
|
||||
|
||||
@@ -90,11 +79,6 @@ public class ActivityServiceImpl implements ActivityService
|
||||
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive;
|
||||
}
|
||||
|
||||
public void setPostDAO(ActivityPostDAO postDAO)
|
||||
{
|
||||
this.postDAO = postDAO;
|
||||
}
|
||||
|
||||
public void setFeedDAO(ActivityFeedDAO feedDAO)
|
||||
{
|
||||
this.feedDAO = feedDAO;
|
||||
@@ -110,11 +94,6 @@ public class ActivityServiceImpl implements ActivityService
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
public void setFeedGenerator(FeedGenerator feedGenerator)
|
||||
{
|
||||
this.feedGenerator = feedGenerator;
|
||||
}
|
||||
|
||||
public void setTenantService(TenantService tenantService)
|
||||
{
|
||||
this.tenantService = tenantService;
|
||||
@@ -125,13 +104,19 @@ public class ActivityServiceImpl implements ActivityService
|
||||
this.siteService = siteService;
|
||||
}
|
||||
|
||||
public void setActivityPostService(ActivityPostService activityPostService)
|
||||
{
|
||||
this.activityPostService = activityPostService;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.activities.ActivityService#postActivity(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, String activityData)
|
||||
{
|
||||
postActivity(activityType, siteId, appTool, activityData, ActivityPostEntity.STATUS.PENDING);
|
||||
// delegate
|
||||
activityPostService.postActivity(activityType, siteId, appTool, activityData);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -139,12 +124,8 @@ public class ActivityServiceImpl implements ActivityService
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("{").append("\"nodeRef\":\"").append(nodeRef.toString()).append("\"").append("}");
|
||||
|
||||
postActivity(activityType, siteId, appTool, sb.toString(), ActivityPostEntity.STATUS.PENDING);
|
||||
// delegate
|
||||
activityPostService.postActivity(activityType, siteId, appTool, nodeRef);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -152,14 +133,8 @@ public class ActivityServiceImpl implements ActivityService
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String name)
|
||||
{
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("{").append("\"nodeRef\":\"").append(nodeRef.toString()).append("\"").append(",")
|
||||
.append("\"name\":\"").append(name).append("\"")
|
||||
.append("}");
|
||||
|
||||
postActivity(activityType, siteId, appTool, sb.toString(), ActivityPostEntity.STATUS.PENDING);
|
||||
// delegate
|
||||
activityPostService.postActivity(activityType, siteId, appTool, nodeRef, name);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -167,132 +142,8 @@ public class ActivityServiceImpl implements ActivityService
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String name, QName typeQName, NodeRef parentNodeRef)
|
||||
{
|
||||
// primarily for delete node activities - eg. delete document, delete folder
|
||||
|
||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||
ParameterCheck.mandatory("typeQName", typeQName);
|
||||
ParameterCheck.mandatory("parentNodeRef", parentNodeRef);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("{").append("\"nodeRef\":\"").append(nodeRef.toString()).append("\"").append(",")
|
||||
.append("\"name\":\"").append(name).append("\"").append(",")
|
||||
.append("\"typeQName\":\"").append(typeQName.toPrefixString()).append("\"").append(",") // TODO toPrefixString does not return prefix ??!!
|
||||
.append("\"parentNodeRef\":\"").append(parentNodeRef.toString()).append("\"")
|
||||
.append("}");
|
||||
|
||||
postActivity(activityType, siteId, appTool, sb.toString(), ActivityPostEntity.STATUS.PENDING);
|
||||
}
|
||||
|
||||
private void postActivity(String activityType, String siteId, String appTool, String activityData, ActivityPostEntity.STATUS status)
|
||||
{
|
||||
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
|
||||
try
|
||||
{
|
||||
// optional - default to empty string
|
||||
if (siteId == null)
|
||||
{
|
||||
siteId = "";
|
||||
}
|
||||
else if (siteId.length() > MAX_LEN_SITE_ID)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid siteId - exceeds " + MAX_LEN_SITE_ID + " chars: " + siteId);
|
||||
}
|
||||
|
||||
// optional - default to empty string
|
||||
if (appTool == null)
|
||||
{
|
||||
appTool = "";
|
||||
}
|
||||
else if (appTool.length() > MAX_LEN_APP_TOOL_ID)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid app tool - exceeds " + MAX_LEN_APP_TOOL_ID + " chars: " + appTool);
|
||||
}
|
||||
|
||||
// required
|
||||
ParameterCheck.mandatoryString("activityType", activityType);
|
||||
|
||||
if (activityType.length() > MAX_LEN_ACTIVITY_TYPE)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid activity type - exceeds " + MAX_LEN_ACTIVITY_TYPE + " chars: " + activityType);
|
||||
}
|
||||
|
||||
// optional - default to empty string
|
||||
if (activityData == null)
|
||||
{
|
||||
activityData = "";
|
||||
}
|
||||
else if (activityType.length() > MAX_LEN_ACTIVITY_DATA)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid activity data - exceeds " + MAX_LEN_ACTIVITY_DATA + " chars: " + activityData);
|
||||
}
|
||||
|
||||
// required
|
||||
ParameterCheck.mandatoryString("currentUser", currentUser);
|
||||
|
||||
if (currentUser.length() > MAX_LEN_USER_ID)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid user - exceeds " + MAX_LEN_USER_ID + " chars: " + currentUser);
|
||||
}
|
||||
else if ((! currentUser.equals(AuthenticationUtil.SYSTEM_USER_NAME)) && (! userNamesAreCaseSensitive))
|
||||
{
|
||||
// user names are not case-sensitive
|
||||
currentUser = currentUser.toLowerCase();
|
||||
}
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
// log error and throw exception
|
||||
logger.error(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Date postDate = new Date();
|
||||
ActivityPostEntity activityPost = new ActivityPostEntity();
|
||||
activityPost.setUserId(currentUser);
|
||||
|
||||
activityPost.setSiteNetwork(tenantService.getName(siteId));
|
||||
|
||||
activityPost.setAppTool(appTool);
|
||||
activityPost.setActivityData(activityData);
|
||||
activityPost.setActivityType(activityType);
|
||||
activityPost.setPostDate(postDate);
|
||||
activityPost.setStatus(status.toString());
|
||||
activityPost.setLastModified(postDate);
|
||||
|
||||
// hash the userid to generate a job task node
|
||||
int nodeCount = feedGenerator.getEstimatedGridSize();
|
||||
int userHashCode = currentUser.hashCode();
|
||||
int nodeHash = (userHashCode % nodeCount) + 1;
|
||||
|
||||
activityPost.setJobTaskNode(nodeHash);
|
||||
|
||||
try
|
||||
{
|
||||
long postId = postDAO.insertPost(activityPost);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
activityPost.setId(postId);
|
||||
logger.debug("Posted: " + activityPost);
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to post activity: " + e, e);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to post activity: " + t, t);
|
||||
}
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
// log error, subsume exception (for post activity)
|
||||
logger.error(e);
|
||||
}
|
||||
// delegate
|
||||
activityPostService.postActivity(activityType, siteId, appTool, nodeRef, name, typeQName, parentNodeRef);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2009 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
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
package org.alfresco.repo.activities.feed;
|
||||
|
||||
import org.alfresco.repo.activities.ActivityPostServiceImpl;
|
||||
import org.alfresco.repo.domain.activities.ActivityPostDAO;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
@@ -44,6 +45,7 @@ public abstract class AbstractFeedGenerator implements FeedGenerator
|
||||
private int maxItemsPerCycle = 100;
|
||||
|
||||
private ActivityPostDAO postDAO;
|
||||
private ActivityPostServiceImpl activityPostServiceImpl;
|
||||
private AuthenticationService authenticationService;
|
||||
|
||||
private String repoEndPoint; // http://hostname:port/webapp (eg. http://localhost:8080/alfresco)
|
||||
@@ -54,6 +56,11 @@ public abstract class AbstractFeedGenerator implements FeedGenerator
|
||||
|
||||
private volatile boolean busy;
|
||||
|
||||
public void setActivityPostServiceImpl(ActivityPostServiceImpl activityPostServiceImpl)
|
||||
{
|
||||
this.activityPostServiceImpl = activityPostServiceImpl;
|
||||
}
|
||||
|
||||
public void setPostDAO(ActivityPostDAO postDAO)
|
||||
{
|
||||
this.postDAO = postDAO;
|
||||
@@ -113,8 +120,11 @@ public abstract class AbstractFeedGenerator implements FeedGenerator
|
||||
private void checkProperties()
|
||||
{
|
||||
PropertyCheck.mandatory(this, "postDAO", postDAO);
|
||||
|
||||
activityPostServiceImpl.setEstimatedGridSize(getEstimatedGridSize());
|
||||
}
|
||||
|
||||
abstract public int getEstimatedGridSize();
|
||||
|
||||
public void execute() throws JobExecutionException
|
||||
{
|
||||
|
@@ -24,8 +24,9 @@
|
||||
*/
|
||||
package org.alfresco.repo.activities.feed.cleanup;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@@ -33,6 +34,8 @@ import org.alfresco.repo.domain.activities.ActivityFeedDAO;
|
||||
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.activities.ActivityService;
|
||||
import org.alfresco.service.cmr.site.SiteService;
|
||||
import org.alfresco.service.cmr.site.SiteVisibility;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
@@ -48,16 +51,23 @@ public class FeedCleanerTest extends TestCase
|
||||
private ActivityFeedDAO feedDAO;
|
||||
private FeedCleaner cleaner;
|
||||
private ActivityService activityService;
|
||||
private SiteService siteService;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
AuthenticationUtil.setRunAsUserSystem();
|
||||
|
||||
activityService = (ActivityService) ctx.getBean("activityService");
|
||||
|
||||
siteService = (SiteService) ctx.getBean("SiteService");
|
||||
feedDAO = (ActivityFeedDAO) ctx.getBean("feedDAO");
|
||||
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||
for (int i = 1; i <= 7; i++)
|
||||
{
|
||||
siteService.createSite("myPreset", "testSite"+i, null, null, SiteVisibility.PUBLIC);
|
||||
}
|
||||
|
||||
AuthenticationUtil.setRunAsUserSystem();
|
||||
|
||||
// construct the test cleaner
|
||||
cleaner = new FeedCleaner();
|
||||
cleaner.setFeedDAO(feedDAO);
|
||||
@@ -68,6 +78,11 @@ public class FeedCleanerTest extends TestCase
|
||||
// clean out any remaining feed entries (allows test to be re-runnable)
|
||||
feedDAO.deleteFeedEntries(new Date(System.currentTimeMillis()+(120*1000L)));
|
||||
|
||||
for (int i = 1; i <= 7; i++)
|
||||
{
|
||||
siteService.deleteSite("testSite"+i);
|
||||
}
|
||||
|
||||
AuthenticationUtil.clearCurrentSecurityContext();
|
||||
}
|
||||
|
||||
@@ -244,24 +259,58 @@ public class FeedCleanerTest extends TestCase
|
||||
cleaner.setMaxAgeMins(1);
|
||||
cleaner.setMaxFeedSize(1);
|
||||
|
||||
final int typeCount = 3;
|
||||
int threadCount = typeCount * 10;
|
||||
int typeCount = 3;
|
||||
int n = typeCount * 10;
|
||||
|
||||
final CountDownLatch endLatch = new CountDownLatch(threadCount);
|
||||
// Kick off the threads
|
||||
for (int i = 0; i < threadCount; i++)
|
||||
Thread[] threads = new Thread[n];
|
||||
Tester[] testers = new Tester[n];
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
Thread thread = new Thread(""+i)
|
||||
Tester tester = new Tester(i, typeCount);
|
||||
testers[i] = tester;
|
||||
|
||||
threads[i] = new Thread(tester);
|
||||
threads[i].start();
|
||||
}
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
@Override
|
||||
threads[i].join();
|
||||
|
||||
if (testers[i].getErrorStackTrace() != null)
|
||||
{
|
||||
fail(testers[i].getErrorStackTrace());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Tester implements Runnable
|
||||
{
|
||||
private int i;
|
||||
private int typeCount;
|
||||
private String errorStackTrace = null;
|
||||
|
||||
public Tester(int i, int typeCount)
|
||||
{
|
||||
this.i = i;
|
||||
this.typeCount = typeCount;
|
||||
}
|
||||
|
||||
public String getErrorStackTrace()
|
||||
{
|
||||
return errorStackTrace;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
int type = new Integer(this.getName()) % typeCount;
|
||||
int type = i % typeCount;
|
||||
|
||||
if (type == 0)
|
||||
{
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||
|
||||
int insertCount = 10;
|
||||
|
||||
// insert some entries
|
||||
@@ -280,36 +329,37 @@ public class FeedCleanerTest extends TestCase
|
||||
feedDAO.insertFeedEntry(feedEntry);
|
||||
}
|
||||
|
||||
System.out.println("["+this.getName()+"] Inserted "+insertCount+" entries");
|
||||
System.out.println("["+i+"] Inserted "+insertCount+" entries");
|
||||
}
|
||||
|
||||
if (type == 1)
|
||||
{
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||
|
||||
// query some entries
|
||||
int selectCount = activityService.getSiteFeedEntries("testSite4", "json").size();
|
||||
|
||||
System.out.println("["+this.getName()+"] Selected "+selectCount+" entries");
|
||||
System.out.println("["+i+"] Selected "+selectCount+" entries");
|
||||
}
|
||||
|
||||
if (type == 2)
|
||||
{
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());
|
||||
|
||||
// clean some entries
|
||||
int deleteCount = cleaner.execute();
|
||||
|
||||
System.out.println("["+this.getName()+"] Deleted "+deleteCount+" entries");
|
||||
System.out.println("["+i+"] Deleted "+deleteCount+" entries");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Throwable t)
|
||||
{
|
||||
fail(e.getMessage());
|
||||
}
|
||||
// Notify of completion
|
||||
endLatch.countDown();
|
||||
}
|
||||
};
|
||||
thread.start();
|
||||
}
|
||||
// Wait for them all to be done
|
||||
endLatch.await();
|
||||
StringWriter sw = new StringWriter();
|
||||
t.printStackTrace(new PrintWriter(sw));
|
||||
errorStackTrace = sw.toString();
|
||||
|
||||
fail(t.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -49,6 +49,7 @@ public class LocalFeedGenerator extends AbstractFeedGenerator
|
||||
this.feedTaskProcessor = feedTaskProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEstimatedGridSize()
|
||||
{
|
||||
return 1;
|
||||
|
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 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.service.cmr.activities;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public interface ActivityPostService
|
||||
{
|
||||
|
||||
/*
|
||||
* Post Activity
|
||||
*/
|
||||
|
||||
/**
|
||||
* Post a custom activity type
|
||||
*
|
||||
* @param activityType - required
|
||||
* @param siteId - optional, if null will be stored as empty string
|
||||
* @param appTool - optional, if null will be stored as empty string
|
||||
* @param jsonActivityData - required
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, String jsonActivityData);
|
||||
|
||||
/**
|
||||
* Post a pre-defined activity type - certain activity data will be looked-up asynchronously, including:
|
||||
*
|
||||
* name (of nodeRef)
|
||||
* displayPath
|
||||
* typeQName
|
||||
* firstName (of posting user)
|
||||
* lastName (of posting user)
|
||||
*
|
||||
* @param activityType - required
|
||||
* @param siteId - optional, if null will be stored as empty string
|
||||
* @param appTool - optional, if null will be stored as empty string
|
||||
* @param nodeRef - required - do not use for deleted (or about to be deleted) nodeRef
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Post a pre-defined activity type - eg. for checked-out nodeRef or renamed nodeRef
|
||||
*
|
||||
* @param activityType - required
|
||||
* @param siteId - optional, if null will be stored as empty string
|
||||
* @param appTool - optional, if null will be stored as empty string
|
||||
* @param nodeRef - required - do not use deleted (or about to be deleted) nodeRef
|
||||
* @param beforeName - optional - name of node (eg. prior to name change)
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String beforeName);
|
||||
|
||||
/**
|
||||
* Post a pre-defined activity type - eg. for deleted nodeRef
|
||||
*
|
||||
* @param activityType - required
|
||||
* @param siteId - optional, if null will be stored as empty string
|
||||
* @param appTool - optional, if null will be stored as empty string
|
||||
* @param nodeRef - required - can be a deleted (or about to be deleted) nodeRef
|
||||
* @param name - optional - name of name
|
||||
* @param typeQName - optional - type of node
|
||||
* @param parentNodeRef - required - used to lookup path/displayPath
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String name, QName typeQName, NodeRef parentNodeRef);
|
||||
}
|
@@ -26,67 +26,8 @@ package org.alfresco.service.cmr.activities;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
public interface ActivityService
|
||||
public interface ActivityService extends ActivityPostService
|
||||
{
|
||||
|
||||
/*
|
||||
* Post Activity
|
||||
*/
|
||||
|
||||
/**
|
||||
* Post a custom activity type
|
||||
*
|
||||
* @param activityType - required
|
||||
* @param siteId - optional, if null will be stored as empty string
|
||||
* @param appTool - optional, if null will be stored as empty string
|
||||
* @param jsonActivityData - required
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, String jsonActivityData);
|
||||
|
||||
/**
|
||||
* Post a pre-defined activity type - certain activity data will be looked-up asynchronously, including:
|
||||
*
|
||||
* name (of nodeRef)
|
||||
* displayPath
|
||||
* typeQName
|
||||
* firstName (of posting user)
|
||||
* lastName (of posting user)
|
||||
*
|
||||
* @param activityType - required
|
||||
* @param siteId - optional, if null will be stored as empty string
|
||||
* @param appTool - optional, if null will be stored as empty string
|
||||
* @param nodeRef - required - do not use for deleted (or about to be deleted) nodeRef
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Post a pre-defined activity type - eg. for checked-out nodeRef or renamed nodeRef
|
||||
*
|
||||
* @param activityType - required
|
||||
* @param siteId - optional, if null will be stored as empty string
|
||||
* @param appTool - optional, if null will be stored as empty string
|
||||
* @param nodeRef - required - do not use deleted (or about to be deleted) nodeRef
|
||||
* @param beforeName - optional - name of node (eg. prior to name change)
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String beforeName);
|
||||
|
||||
/**
|
||||
* Post a pre-defined activity type - eg. for deleted nodeRef
|
||||
*
|
||||
* @param activityType - required
|
||||
* @param siteId - optional, if null will be stored as empty string
|
||||
* @param appTool - optional, if null will be stored as empty string
|
||||
* @param nodeRef - required - can be a deleted (or about to be deleted) nodeRef
|
||||
* @param name - optional - name of name
|
||||
* @param typeQName - optional - type of node
|
||||
* @param parentNodeRef - required - used to lookup path/displayPath
|
||||
*/
|
||||
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String name, QName typeQName, NodeRef parentNodeRef);
|
||||
|
||||
|
||||
/*
|
||||
* Retrieve Feed Entries
|
||||
*/
|
||||
|
Reference in New Issue
Block a user