ALF-9957 - MT: test and fix subscriptions (followers)

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30999 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2011-10-06 12:16:59 +00:00
parent fddcc01209
commit 4b6325059e
6 changed files with 285 additions and 177 deletions

View File

@@ -87,6 +87,7 @@
<property name="contentService" ref="ContentService"/> <property name="contentService" ref="ContentService"/>
<property name="permissionService" ref="PermissionService"/> <property name="permissionService" ref="PermissionService"/>
<property name="subscriptionService" ref="SubscriptionService"/> <property name="subscriptionService" ref="SubscriptionService"/>
<property name="tenantService" ref="tenantService"/>
<property name="templateSearchPaths"> <property name="templateSearchPaths">
<list> <list>

View File

@@ -171,32 +171,13 @@ public class ActivityPostServiceImpl implements ActivityPostService
if (AuthenticationUtil.isMtEnabled()) if (AuthenticationUtil.isMtEnabled())
{ {
// MT share - required for canRead // MT share - add tenantDomain
try try
{ {
JSONObject jo = new JSONObject(new JSONTokener(activityData)); JSONObject jo = new JSONObject(new JSONTokener(activityData));
jo.put(PostLookup.JSON_TENANT_DOMAIN, tenantService.getCurrentUserDomain());
boolean update = false;
if (! jo.isNull(PostLookup.JSON_NODEREF))
{
String nodeRefStr = jo.getString(PostLookup.JSON_NODEREF);
jo.put(PostLookup.JSON_NODEREF, tenantService.getName(new NodeRef(nodeRefStr)));
update = true;
}
if (! jo.isNull(PostLookup.JSON_NODEREF_PARENT))
{
String nodeRefStr = jo.getString(PostLookup.JSON_NODEREF_PARENT);
jo.put(PostLookup.JSON_NODEREF_PARENT, tenantService.getName(new NodeRef(nodeRefStr)));
update = true;
}
if (update)
{
activityData = jo.toString(); activityData = jo.toString();
} }
}
catch (JSONException e) catch (JSONException e)
{ {
throw new IllegalArgumentException("Invalid activity data - not valid JSON: " + e); throw new IllegalArgumentException("Invalid activity data - not valid JSON: " + e);

View File

@@ -38,11 +38,13 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import org.alfresco.repo.activities.post.lookup.PostLookup;
import org.alfresco.repo.domain.activities.ActivityFeedDAO; import org.alfresco.repo.domain.activities.ActivityFeedDAO;
import org.alfresco.repo.domain.activities.ActivityFeedEntity; import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.domain.activities.ActivityPostEntity; import org.alfresco.repo.domain.activities.ActivityPostEntity;
import org.alfresco.repo.domain.activities.FeedControlEntity; import org.alfresco.repo.domain.activities.FeedControlEntity;
import org.alfresco.repo.template.ISO8601DateFormatMethod; import org.alfresco.repo.template.ISO8601DateFormatMethod;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.util.JSONtoFmModel; import org.alfresco.util.JSONtoFmModel;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -207,7 +209,27 @@ public abstract class FeedTaskProcessor
continue; continue;
} }
String thisSite = (activityPost.getSiteNetwork() != null ? activityPost.getSiteNetwork() : ""); // note: for MT share, site id should already be mangled - in addition to extra tenant domain info
String thisSite = activityPost.getSiteNetwork();
String tenantDomain = (String)model.get(PostLookup.JSON_TENANT_DOMAIN);
if (thisSite != null)
{
if (tenantDomain != null)
{
thisSite = getTenantName(thisSite, tenantDomain);
}
else
{
// for backwards compatibility
tenantDomain = getTenantDomain(thisSite);
}
}
if (tenantDomain == null)
{
tenantDomain = TenantService.DEFAULT_DOMAIN;
}
model.put(ActivityFeedEntity.KEY_ACTIVITY_FEED_TYPE, activityPost.getActivityType()); model.put(ActivityFeedEntity.KEY_ACTIVITY_FEED_TYPE, activityPost.getActivityType());
model.put(ActivityFeedEntity.KEY_ACTIVITY_FEED_SITE, thisSite); model.put(ActivityFeedEntity.KEY_ACTIVITY_FEED_SITE, thisSite);
@@ -230,7 +252,7 @@ public abstract class FeedTaskProcessor
try try
{ {
// Repository callback to get site members // Repository callback to get site members
connectedUsers = getSiteMembers(ctx, thisSite); connectedUsers = getSiteMembers(ctx, thisSite, tenantDomain);
connectedUsers.add(""); // add empty posting userid - to represent site feed ! connectedUsers.add(""); // add empty posting userid - to represent site feed !
} }
catch(Exception e) catch(Exception e)
@@ -248,11 +270,15 @@ public abstract class FeedTaskProcessor
} }
// Add followers to recipient list // Add followers to recipient list
Set<String> followerUsers = followers.get(activityPost.getUserId());
if(followerUsers == null) { // MT Share - mangle key to be within context of tenant
String key = getTenantKey(activityPost.getUserId(), tenantDomain);
Set<String> followerUsers = followers.get(key);
if (followerUsers == null)
{
try try
{ {
followerUsers = getFollowers(activityPost.getUserId()); followerUsers = getFollowers(activityPost.getUserId(), tenantDomain);
} }
catch(Exception e) catch(Exception e)
{ {
@@ -261,7 +287,7 @@ public abstract class FeedTaskProcessor
continue; continue;
} }
followers.put(activityPost.getUserId(), followerUsers); followers.put(key, followerUsers);
} }
recipients.addAll(followerUsers); recipients.addAll(followerUsers);
@@ -473,8 +499,26 @@ public abstract class FeedTaskProcessor
return result; return result;
} }
protected Set<String> getSiteMembers(RepoCtx ctx, String siteId) throws Exception protected String getTenantName(String name, String tenantDomain)
{ {
// note: for MT impl, see override in LocalFeedTaskProcessor
return name;
}
protected String getTenantDomain(String name)
{
// note: for MT impl, see override in LocalFeedTaskProcessor
return TenantService.DEFAULT_DOMAIN;
}
private static String getTenantKey(String name, String tenantDomain)
{
return tenantDomain + "." + name;
}
protected Set<String> getSiteMembers(RepoCtx ctx, String siteId, String tenantDomain) throws Exception
{
// note: tenant domain ignored her - it should already be part of the siteId
Set<String> members = new HashSet<String>(); Set<String> members = new HashSet<String>();
if ((siteId != null) && (siteId.length() != 0)) if ((siteId != null) && (siteId.length() != 0))
{ {
@@ -504,7 +548,8 @@ public abstract class FeedTaskProcessor
return members; return members;
} }
protected abstract Set<String> getFollowers(String userId) throws Exception;
protected abstract Set<String> getFollowers(String userId, String tenantDomain) throws Exception;
protected boolean canRead(RepoCtx ctx, final String connectedUser, Map<String, Object> model) throws Exception protected boolean canRead(RepoCtx ctx, final String connectedUser, Map<String, Object> model) throws Exception
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2011 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingRequest;
import org.alfresco.repo.activities.feed.FeedTaskProcessor; import org.alfresco.repo.activities.feed.FeedTaskProcessor;
import org.alfresco.repo.activities.feed.RepoCtx; import org.alfresco.repo.activities.feed.RepoCtx;
@@ -38,6 +39,7 @@ import org.alfresco.repo.domain.activities.FeedControlDAO;
import org.alfresco.repo.domain.activities.FeedControlEntity; import org.alfresco.repo.domain.activities.FeedControlEntity;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.template.ClassPathRepoTemplateLoader; import org.alfresco.repo.template.ClassPathRepoTemplateLoader;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
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;
@@ -78,6 +80,7 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor implements Applica
private ContentService contentService; private ContentService contentService;
private PermissionService permissionService; private PermissionService permissionService;
private SubscriptionService subscriptionService; private SubscriptionService subscriptionService;
private TenantService tenantService;
private String defaultEncoding; private String defaultEncoding;
private List<String> templateSearchPaths; private List<String> templateSearchPaths;
@@ -124,6 +127,11 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor implements Applica
this.subscriptionService = subscriptionService; this.subscriptionService = subscriptionService;
} }
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
public void setDefaultEncoding(String defaultEncoding) public void setDefaultEncoding(String defaultEncoding)
{ {
this.defaultEncoding = defaultEncoding; this.defaultEncoding = defaultEncoding;
@@ -185,15 +193,52 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor implements Applica
} }
@Override @Override
protected Set<String> getSiteMembers(final RepoCtx ctx, final String siteId) throws Exception protected String getTenantName(String name, String tenantDomain)
{
if (name == null)
{
return name;
}
String nameDomain = getTenantDomain(name);
if (nameDomain.equals(TenantService.DEFAULT_DOMAIN))
{
if (! TenantService.DEFAULT_DOMAIN.equals(tenantDomain))
{
// no domain, so add it as a prefix (between two domain separators)
name = TenantService.SEPARATOR + tenantDomain + TenantService.SEPARATOR + name;
}
}
else
{
if (! tenantDomain.equals(nameDomain))
{
throw new AlfrescoRuntimeException("domain mismatch: expected = " + tenantDomain + ", actual = " + nameDomain);
}
}
return name;
}
@Override
protected String getTenantDomain(String name)
{
return tenantService.getDomain(name, false);
}
@Override
protected Set<String> getSiteMembers(final RepoCtx ctx, String siteIdIn, final String tenantDomain) throws Exception
{ {
if (useRemoteCallbacks) if (useRemoteCallbacks)
{ {
// as per 3.0, 3.1 // as per 3.0, 3.1
return super.getSiteMembers(ctx, siteId); return super.getSiteMembers(ctx, siteIdIn, tenantDomain);
} }
else else
{ {
final String siteId = tenantService.getBaseName(siteIdIn, true);
// optimise for non-remote implementation - override remote repo callback (to "List Site Memberships" web script) with embedded call // optimise for non-remote implementation - override remote repo callback (to "List Site Memberships" web script) with embedded call
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Set<String>>() return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Set<String>>()
{ {
@@ -219,7 +264,7 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor implements Applica
return members; return members;
} }
}, AuthenticationUtil.getSystemUserName()); }, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
} }
} }
@@ -248,13 +293,17 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor implements Applica
{ {
final NodeRef nodeRef = new NodeRef(nodeRefStr); final NodeRef nodeRef = new NodeRef(nodeRefStr);
// MT share
String tenantDomain = (String)model.get(PostLookup.JSON_TENANT_DOMAIN);
if (tenantDomain == null) { tenantDomain = TenantService.DEFAULT_DOMAIN; }
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Boolean>() return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Boolean>()
{ {
public Boolean doWork() throws Exception public Boolean doWork() throws Exception
{ {
return canReadImpl(connectedUser, nodeRef); return canReadImpl(connectedUser, nodeRef);
} }
}, AuthenticationUtil.getSystemUserName()); }, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
} }
return true; return true;
@@ -447,11 +496,15 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor implements Applica
return documentPaths; return documentPaths;
} }
protected Set<String> getFollowers(String userId) throws Exception protected Set<String> getFollowers(final String userId, String tenantDomain) throws Exception
{ {
Set<String> result = new HashSet<String>(); final Set<String> result = new HashSet<String>();
if (subscriptionService.isActive()) if (subscriptionService.isActive())
{
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>()
{
public Void doWork() throws Exception
{ {
PagingFollowingResults fr = subscriptionService.getFollowers(userId, new PagingRequest(1000000, null)); PagingFollowingResults fr = subscriptionService.getFollowers(userId, new PagingRequest(1000000, null));
@@ -459,6 +512,10 @@ public class LocalFeedTaskProcessor extends FeedTaskProcessor implements Applica
{ {
result.addAll(fr.getPage()); result.addAll(fr.getPage());
} }
return null;
}
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
} }
return result; return result;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2011 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -76,6 +76,8 @@ public class PostLookup
public static final String JSON_PARENT_NODEREF = "parentNodeRef"; public static final String JSON_PARENT_NODEREF = "parentNodeRef";
public static final String JSON_DISPLAY_PATH = "displayPath"; public static final String JSON_DISPLAY_PATH = "displayPath";
public static final String JSON_TENANT_DOMAIN = "tenantDomain";
public void setPostDAO(ActivityPostDAO postDAO) public void setPostDAO(ActivityPostDAO postDAO)
{ {
@@ -149,8 +151,16 @@ public class PostLookup
{ {
final String postUserId = activityPost.getUserId(); final String postUserId = activityPost.getUserId();
try
{
// MT share // MT share
String tenantDomain = tenantService.getUserDomain(postUserId); String tenantDomain = TenantService.DEFAULT_DOMAIN;
final JSONObject jo = new JSONObject(new JSONTokener(activityPost.getActivityData()));
if (! jo.isNull(JSON_TENANT_DOMAIN))
{
tenantDomain = jo.getString(JSON_TENANT_DOMAIN);
}
AuthenticationUtil.runAs(new RunAsWork<Object>() AuthenticationUtil.runAs(new RunAsWork<Object>()
{ {
@@ -160,8 +170,6 @@ public class PostLookup
{ {
postDAO.startTransaction(); postDAO.startTransaction();
JSONObject jo = new JSONObject(new JSONTokener(activityPost.getActivityData()));
String activityDataStr = null; String activityDataStr = null;
if (! jo.isNull(JSON_NODEREF_LOOKUP)) if (! jo.isNull(JSON_NODEREF_LOOKUP))
@@ -244,6 +252,22 @@ public class PostLookup
} }
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain)); }, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
} }
catch (JSONException e)
{
// log error, but consume exception (skip this post)
logger.error("Skipping activity post " + activityPost.getId() + ": " + e);
try
{
postDAO.updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.ERROR);
postDAO.commitTransaction();
}
finally
{
postDAO.endTransaction();
}
}
}
} }
catch (SQLException e) catch (SQLException e)
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2011 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -538,7 +538,7 @@ public class MultiTServiceImpl implements TenantService
*/ */
public boolean isTenantName(String name) public boolean isTenantName(String name)
{ {
return false == getDomain(name, false).isEmpty(); return (! TenantService.DEFAULT_DOMAIN.equals(getDomain(name, false)));
} }
/* (non-Javadoc) /* (non-Javadoc)