Merged DEV to HEAD:

30289, 30366, 30381, 30607: (record-only)
    30621, 30658, 30674, 30689, 30700: MT-aware Solr (THOR-129) - enabler only (subject to QA)


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@31975 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2011-11-15 12:02:28 +00:00
parent fa9b63c5ff
commit 5c2a68bdd2
9 changed files with 155 additions and 90 deletions

View File

@@ -93,6 +93,7 @@ public class CmisFunctionEvaluationContext implements FunctionEvaluationContext
EXPOSED_FIELDS.add(AbstractLuceneQueryParser.FIELD_PRIMARYASSOCTYPEQNAME);
EXPOSED_FIELDS.add(AbstractLuceneQueryParser.FIELD_DBID);
EXPOSED_FIELDS.add(AbstractLuceneQueryParser.FIELD_TAG);
EXPOSED_FIELDS.add(AbstractLuceneQueryParser.FIELD_TENANT);
EXPOSED_FIELDS.add(AbstractLuceneQueryParser.FIELD_ANCESTOR);

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
*
@@ -23,9 +23,7 @@ import org.alfresco.repo.search.IndexerException;
import org.alfresco.repo.search.QueryRegisterComponent;
import org.alfresco.repo.search.SearcherException;
import org.alfresco.repo.search.impl.NoActionIndexer;
import org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl;
import org.alfresco.repo.search.impl.lucene.AbstractIndexerAndSearcher;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
@@ -43,7 +41,6 @@ public class SolrIndexerAndSearcherFactory extends AbstractIndexerAndSearcher
private NamespacePrefixResolver namespacePrefixResolver;
private NodeService nodeService;
private QueryRegisterComponent queryRegister;
private TenantService tenantService;
private String baseUrl;
public DictionaryService getDictionaryService()
@@ -86,16 +83,6 @@ public class SolrIndexerAndSearcherFactory extends AbstractIndexerAndSearcher
this.queryRegister = queryRegister;
}
public TenantService getTenantService()
{
return tenantService;
}
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
public String getBaseUrl()
{
return baseUrl;
@@ -121,15 +108,12 @@ public class SolrIndexerAndSearcherFactory extends AbstractIndexerAndSearcher
@Override
public SearchService getSearcher(StoreRef storeRef, boolean searchDelta) throws SearcherException
{
//storeRef = tenantService.getName(storeRef);
SolrSearchService searchService = new SolrSearchService();
searchService.setDictionaryService(dictionaryService);
searchService.setNamespacePrefixResolver(namespacePrefixResolver);
searchService.setNodeService(nodeService);
searchService.setQueryLanguages(getQueryLanguages());
searchService.setQueryRegister(queryRegister);
searchService.setTenantService(tenantService);
return searchService;
}

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
*
@@ -30,15 +30,14 @@ import javax.servlet.http.HttpServletResponse;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.httpclient.HttpClientFactory;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParserException;
import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchParameters.FieldFacet;
import org.alfresco.service.cmr.search.SearchParameters.FieldFacetMethod;
@@ -76,6 +75,8 @@ public class SolrQueryHTTPClient
private NodeService nodeService;
private PermissionService permissionService;
private TenantService tenantService;
private Map<String, String> languageMappings;
@@ -121,6 +122,11 @@ public class SolrQueryHTTPClient
{
this.permissionService = permissionService;
}
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
public void setLanguageMappings(Map<String, String> languageMappings)
{
@@ -136,11 +142,6 @@ public class SolrQueryHTTPClient
{
try
{
// Simple demo
// FieldFacet ff = new FieldFacet("@"+ContentModel.PROP_NAME);
// ff.setLimit(2);
// searchParameters.addFieldFacet(ff);
URLCodec encoder = new URLCodec();
StringBuilder url = new StringBuilder();
url.append(baseUrl);
@@ -216,25 +217,9 @@ public class SolrQueryHTTPClient
}
url.append(sortBuffer);
// Authorities go over in body
StringBuilder authQuery = new StringBuilder();
for (String authority : permissionService.getAuthorisations())
{
if (authQuery.length() > 0)
{
authQuery.append(" ");
}
authQuery.append("|AUTHORITY:\"").append(authority).append("\"");
}
// url.append("&fq=");
// encoder = new URLCodec();
// url.append(encoder.encode(authQuery.toString(), "UTF-8"));
url.append("&fq=").append(encoder.encode("{!afts}AUTHORITY_FILTER_FROM_JSON", "UTF-8"));
// facets would go on url?
url.append("&fq=").append(encoder.encode("{!afts}TENANT_FILTER_FROM_JSON", "UTF-8"));
if(searchParameters.getFieldFacets().size() > 0)
{
@@ -275,9 +260,20 @@ public class SolrQueryHTTPClient
JSONObject body = new JSONObject();
body.put("query", searchParameters.getQuery());
// body.put("defaultField", searchParameters.getDefaultFieldName());
body.put("filter", authQuery);
// Authorities go over as is - and tenant mangling and query building takes place on the SOLR side
JSONArray authorities = new JSONArray();
for (String authority : permissionService.getAuthorisations())
{
authorities.put(authority);
}
body.put("authorities", authorities);
JSONArray tenants = new JSONArray();
tenants.put(tenantService.getCurrentUserDomain());
body.put("tenants", tenants);
JSONArray locales = new JSONArray();
for (Locale currentLocale : searchParameters.getLocales())

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
*
@@ -34,7 +34,6 @@ import org.alfresco.repo.search.impl.NodeSearcher;
import org.alfresco.repo.search.impl.lucene.LuceneQueryLanguageSPI;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.lucene.QueryParameterisationException;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -46,8 +45,8 @@ import org.alfresco.service.cmr.search.QueryParameter;
import org.alfresco.service.cmr.search.QueryParameterDefinition;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.search.SearchParameters.Operator;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ISO9075;
@@ -58,11 +57,8 @@ import org.alfresco.util.SearchLanguageConversion;
*/
public class SolrSearchService implements SearchService
{
private NodeService nodeService;
private TenantService tenantService;
private NamespacePrefixResolver namespacePrefixResolver;
private DictionaryService dictionaryService;
@@ -81,16 +77,6 @@ public class SolrSearchService implements SearchService
this.nodeService = nodeService;
}
public TenantService getTenantService()
{
return tenantService;
}
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
public NamespacePrefixResolver getNamespacePrefixResolver()
{
return namespacePrefixResolver;
@@ -150,8 +136,6 @@ public class SolrSearchService implements SearchService
@Override
public ResultSet query(StoreRef store, String language, String query, QueryParameterDefinition[] queryParameterDefinitions)
{
store = tenantService.getName(store);
SearchParameters sp = new SearchParameters();
sp.addStore(store);
sp.setLanguage(language);
@@ -164,10 +148,10 @@ public class SolrSearchService implements SearchService
}
}
sp.excludeDataInTheCurrentTransaction(true);
return query(sp);
}
/*
* (non-Javadoc)
* @see org.alfresco.service.cmr.search.SearchService#query(org.alfresco.service.cmr.repository.StoreRef,
@@ -337,10 +321,7 @@ public class SolrSearchService implements SearchService
{
throw new IllegalStateException("Only one store can be searched at present");
}
ArrayList<StoreRef> stores = searchParameters.getStores();
stores.set(0, tenantService.getName(searchParameters.getStores().get(0)));
String parameterisedQueryString;
if (searchParameters.getQueryParameterDefinitions().size() > 0)
{

View File

@@ -20,6 +20,8 @@ package org.alfresco.repo.solr;
import java.util.Set;
import org.alfresco.repo.tenant.TenantService;
/**
* Bean for SOLR ACL readers.
*
@@ -31,11 +33,12 @@ public class AclReaders
private Long aclId;
private Set<String> readers;
private long aclChangeSetId;
private String tenantDomain = TenantService.DEFAULT_DOMAIN;
@Override
public String toString()
{
return "AclReaders [aclId=" + aclId + ", readers=" + readers + ", aclChangeSetId=" + aclChangeSetId + "]";
return "AclReaders [aclId=" + aclId + ", readers=" + readers + ", aclChangeSetId=" + aclChangeSetId + ", tenantDomain=" + tenantDomain + "]";
}
public Long getAclId()
{
@@ -61,5 +64,12 @@ public class AclReaders
{
this.aclChangeSetId = aclChangeSetId;
}
public String getTenantDomain()
{
return tenantDomain;
}
public void setTenantDomain(String tenantDomain)
{
this.tenantDomain = tenantDomain;
}
}

View File

@@ -23,7 +23,6 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.CRC32;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -50,6 +49,7 @@ public class NodeMetaData
private Long parentAssocsCrc;
private List<Long> childIds;
private Long txnId;
private String tenantDomain;
public String getOwner()
{
@@ -156,6 +156,13 @@ public class NodeMetaData
public void setTxnId(Long txnId)
{
this.txnId = txnId;
}
}
public String getTenantDomain()
{
return tenantDomain;
}
public void setTenantDomain(String tenantDomain)
{
this.tenantDomain = tenantDomain;
}
}

View File

@@ -39,6 +39,7 @@ import org.alfresco.repo.domain.node.NodeDAO.ChildAssocRefQueryCallback;
import org.alfresco.repo.domain.permissions.AclDAO;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.repo.domain.solr.SOLRDAO;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
@@ -185,6 +186,8 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent
* This is an N+1 query that should, in theory, make use of cached ACL readers data.
*/
Map<Long, String> aclChangeSetTenant = new HashMap<Long, String>(aclIds.size());
List<AclReaders> aclsReaders = new ArrayList<AclReaders>(aclIds.size() * 10);
for (Long aclId : aclIds)
{
@@ -192,10 +195,30 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent
AclReaders readers = new AclReaders();
readers.setAclId(aclId);
readers.setReaders(readersSet);
readers.setAclChangeSetId(aclDAO.getAccessControlList(aclId).getProperties().getAclChangeSetId());
Long aclChangeSetId = aclDAO.getAccessControlList(aclId).getProperties().getAclChangeSetId();
readers.setAclChangeSetId(aclChangeSetId);
if (AuthenticationUtil.isMtEnabled())
{
// MT - for now, derive the tenant for acl (via acl change set)
String tenantDomain = aclChangeSetTenant.get(aclChangeSetId);
if (tenantDomain == null)
{
tenantDomain = getTenant(aclId, aclChangeSetId);
if (tenantDomain == null)
{
// skip this acl !
continue;
}
aclChangeSetTenant.put(aclChangeSetId, tenantDomain);
}
readers.setTenantDomain(tenantDomain);
}
aclsReaders.add(readers);
}
return aclsReaders;
}
else
@@ -203,7 +226,51 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent
return Collections.<AclReaders>emptyList();
}
}
private String getTenant(long aclId, long aclChangeSetId)
{
String tenantDomain = getAclTenant(aclId);
if (tenantDomain == null)
{
List<Long> aclChangeSetIds = new ArrayList<Long>(1);
aclChangeSetIds.add(aclChangeSetId);
List<Acl> acls = solrDAO.getAcls(aclChangeSetIds, null, 1024);
for (Acl acl : acls)
{
tenantDomain = getAclTenant(acl.getId());
if (tenantDomain != null)
{
break;
}
}
if (tenantDomain == null)
{
// tenant not found - log warning ?
tenantDomain = null; // temp - for debug breakpoint only
}
}
return tenantDomain;
}
private String getAclTenant(long aclId)
{
List<Long> nodeIds = aclDAO.getADMNodesByAcl(aclId, 1);
if (nodeIds.size() == 0)
{
return null;
}
Pair<Long, NodeRef> nodePair = nodeDAO.getNodePair(nodeIds.get(0));
if (nodePair == null)
{
return null;
}
return tenantService.getDomain(nodePair.getSecond().getStoreRef().getIdentifier());
}
@Override
public List<Transaction> getTransactions(Long minTxnId, Long fromCommitTime, int maxResults)
{
@@ -519,12 +586,16 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent
nodeMetaData.setPaths(paths);
}
NodeRef nodeRef = pair.getSecond();
if(includeNodeRef)
{
nodeMetaData.setNodeRef(pair.getSecond());
nodeMetaData.setNodeRef(tenantService.getBaseName(nodeRef, true));
}
nodeMetaData.setTenantDomain(tenantService.getDomain(nodeRef.getStoreRef().getIdentifier()));
if(includeChildAssociations)
{
final List<ChildAssociationRef> childAssocs = new ArrayList<ChildAssociationRef>(100);
@@ -546,7 +617,7 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent
public boolean handle(Pair<Long, ChildAssociationRef> childAssocPair, Pair<Long, NodeRef> parentNodePair,
Pair<Long, NodeRef> childNodePair)
{
childAssocs.add(childAssocPair.getSecond());
childAssocs.add(tenantService.getBaseName(childAssocPair.getSecond(), true));
return true;
}
@@ -612,7 +683,7 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent
public boolean handle(Pair<Long, ChildAssociationRef> childAssocPair,
Pair<Long, NodeRef> parentNodePair, Pair<Long, NodeRef> childNodePair)
{
parentAssocs.add(childAssocPair.getSecond());
parentAssocs.add(tenantService.getBaseName(childAssocPair.getSecond(), true));
return true;
}

View File

@@ -277,10 +277,17 @@ public class MultiTServiceImpl implements TenantService
* @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.cmr.repository.NodeRef)
*/
public NodeRef getBaseName(NodeRef nodeRef)
{
{
return getBaseName(nodeRef, false);
}
/* (non-Javadoc)
* @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.cmr.repository.NodeRef, boolean)
*/
public NodeRef getBaseName(NodeRef nodeRef, boolean forceForNonTenant)
{
if (nodeRef == null) { return null; }
return new NodeRef(nodeRef.getStoreRef().getProtocol(), getBaseName(nodeRef.getStoreRef().getIdentifier()), nodeRef.getId());
return new NodeRef(nodeRef.getStoreRef().getProtocol(), getBaseName(nodeRef.getStoreRef().getIdentifier(), forceForNonTenant), nodeRef.getId());
}
/* (non-Javadoc)
@@ -298,13 +305,21 @@ public class MultiTServiceImpl implements TenantService
*/
public ChildAssociationRef getBaseName(ChildAssociationRef childAssocRef)
{
return getBaseName(childAssocRef, false);
}
/* (non-Javadoc)
* @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
*/
public ChildAssociationRef getBaseName(ChildAssociationRef childAssocRef, boolean forceForNonTenant)
{
if (childAssocRef == null) { return null; }
return new ChildAssociationRef(
childAssocRef.getTypeQName(),
getBaseName(childAssocRef.getParentRef()),
getBaseName(childAssocRef.getParentRef(), forceForNonTenant),
childAssocRef.getQName(),
getBaseName(childAssocRef.getChildRef()),
getBaseName(childAssocRef.getChildRef(), forceForNonTenant),
childAssocRef.isPrimary(),
childAssocRef.getNthSibling());
}