From 6e3ab8a166df30187c8242f8dda947b55704c86c Mon Sep 17 00:00:00 2001 From: Andrew Hind Date: Tue, 1 Nov 2016 22:00:11 +0000 Subject: [PATCH] Fix for SEARCH-228 SOLR - version store nodes are indexed with the wrong ACL and PATH - Index the ACL and PATHs for the current live version (which will not be updated). git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@132065 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repo/solr/SOLRTrackingComponentImpl.java | 184 ++++++++++++------ 1 file changed, 124 insertions(+), 60 deletions(-) diff --git a/source/java/org/alfresco/repo/solr/SOLRTrackingComponentImpl.java b/source/java/org/alfresco/repo/solr/SOLRTrackingComponentImpl.java index 53e53b0d4f..ac845a5685 100644 --- a/source/java/org/alfresco/repo/solr/SOLRTrackingComponentImpl.java +++ b/source/java/org/alfresco/repo/solr/SOLRTrackingComponentImpl.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ package org.alfresco.repo.solr; import java.io.Serializable; @@ -52,10 +52,13 @@ import org.alfresco.repo.domain.solr.SOLRDAO; import org.alfresco.repo.index.shard.ShardRegistry; import org.alfresco.repo.index.shard.ShardState; import org.alfresco.repo.search.AspectIndexFilter; -import org.alfresco.repo.search.TypeIndexFilter; -import org.alfresco.repo.search.impl.QueryParserUtils; +import org.alfresco.repo.search.TypeIndexFilter; +import org.alfresco.repo.search.impl.QueryParserUtils; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.tenant.TenantService; +import org.alfresco.repo.version.Version2Model; +import org.alfresco.repo.version.VersionModel; +import org.alfresco.repo.version.common.VersionUtil; import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; @@ -70,13 +73,11 @@ import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.Path.ChildAssocElement; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.security.OwnableService; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; -import org.alfresco.util.PropertyCheck; - -import com.sun.xml.txw2.NamespaceResolver; +import org.alfresco.util.PropertyCheck; /** * Component providing data for SOLR tracking @@ -98,7 +99,7 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent private boolean cacheAncestors =true; private TypeIndexFilter typeIndexFilter; private AspectIndexFilter aspectIndexFilter; - private ShardRegistry shardRegistry; + private ShardRegistry shardRegistry; private NamespaceService namespaceService; @@ -182,11 +183,11 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent this.shardRegistry = shardRegistry; } - public void setNamespaceService(NamespaceService namespaceService) - { - this.namespaceService = namespaceService; - } - + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + /** * Initialize */ @@ -202,7 +203,7 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent PropertyCheck.mandatory(this, "dictionaryDAO", dictionaryDAO); PropertyCheck.mandatory(this, "aclDAO", aclDAO); PropertyCheck.mandatory(this, "typeIndexFilter", typeIndexFilter); - PropertyCheck.mandatory(this, "aspectIndexFilter", aspectIndexFilter); + PropertyCheck.mandatory(this, "aspectIndexFilter", aspectIndexFilter); PropertyCheck.mandatory(this, "namespaceService", namespaceService); } @@ -354,21 +355,21 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent public void getNodes(NodeParameters nodeParameters, NodeQueryCallback callback) { if(enabled) - { - QName shardPropertQName = null; - if(nodeParameters.getShardProperty() != null) - { - PropertyDefinition pdef = QueryParserUtils.matchPropertyDefinition(NamespaceService.CONTENT_MODEL_1_0_URI, namespaceService, dictionaryService, nodeParameters.getShardProperty()); - if(pdef == null) - { - throw new AlfrescoRuntimeException("Invalid shard property: "+nodeParameters.getShardProperty()); - } - if((!pdef.getDataType().getName().equals(DataTypeDefinition.TEXT)) && (!pdef.getDataType().getName().equals(DataTypeDefinition.DATE)) && (!pdef.getDataType().getName().equals(DataTypeDefinition.DATETIME))) - { - throw new AlfrescoRuntimeException("Unsupported shard property type: "+(pdef.getDataType().getName() + " for " +nodeParameters.getShardProperty())); - } - shardPropertQName = pdef.getName(); - } + { + QName shardPropertQName = null; + if(nodeParameters.getShardProperty() != null) + { + PropertyDefinition pdef = QueryParserUtils.matchPropertyDefinition(NamespaceService.CONTENT_MODEL_1_0_URI, namespaceService, dictionaryService, nodeParameters.getShardProperty()); + if(pdef == null) + { + throw new AlfrescoRuntimeException("Invalid shard property: "+nodeParameters.getShardProperty()); + } + if((!pdef.getDataType().getName().equals(DataTypeDefinition.TEXT)) && (!pdef.getDataType().getName().equals(DataTypeDefinition.DATE)) && (!pdef.getDataType().getName().equals(DataTypeDefinition.DATETIME))) + { + throw new AlfrescoRuntimeException("Unsupported shard property type: "+(pdef.getDataType().getName() + " for " +nodeParameters.getShardProperty())); + } + shardPropertQName = pdef.getName(); + } List nodes = solrDAO.getNodes(nodeParameters, shardPropertQName); @@ -685,9 +686,9 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent public long getCRC(Long nodeId) { - Status status = nodeDAO.getNodeIdStatus(nodeId); - Set aspects = getNodeAspects(nodeId); - Map props = getProperties(nodeId); + //Status status = nodeDAO.getNodeIdStatus(nodeId); + //Set aspects = getNodeAspects(nodeId); + //Map props = getProperties(nodeId); //Category membership does not cascade to children - only the node needs reindexing, not its children //This was producing cascade updates that were not required @@ -781,6 +782,12 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent continue; } NodeRef nodeRef = status.getNodeRef(); + + NodeRef unversionedNodeRef = null; + if(isVersionNodeRef(nodeRef)) + { + unversionedNodeRef = convertVersionNodeRefToVersionedNodeRef(VersionUtil.convertNodeRef(nodeRef)); + } NodeMetaData nodeMetaData = new NodeMetaData(); nodeMetaData.setNodeId(nodeId); @@ -803,8 +810,22 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent Map props = null; Set aspects = null; - - nodeMetaData.setAclId(nodeDAO.getNodeAclId(nodeId)); + + Status unversionedStatus = null; + if(unversionedNodeRef != null) + { + unversionedStatus = nodeDAO.getNodeRefStatus(unversionedNodeRef); + } + + if(unversionedStatus != null) + { + nodeMetaData.setAclId(nodeDAO.getNodeAclId(unversionedStatus.getDbId())); + } + else + { + nodeMetaData.setAclId(nodeDAO.getNodeAclId(nodeId)); + } + if(includeType) { @@ -903,8 +924,8 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent } List directPaths = nodeDAO.getPaths(new Pair(nodeId, status.getNodeRef()), false); - Collection> paths = new ArrayList>(directPaths.size() + categoryPaths.getPaths().size()); + for (Path path : directPaths) { paths.add(new Pair(path.getBaseNamePath(tenantService), null)); @@ -913,6 +934,14 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent { paths.add(new Pair(catPair.getFirst().getBaseNamePath(tenantService), catPair.getSecond())); } + if(unversionedStatus != null) + { + List unversionedPaths = nodeDAO.getPaths(new Pair(unversionedStatus.getDbId(), unversionedStatus.getNodeRef()), false); + for (Path path : unversionedPaths) + { + paths.add(new Pair(path.getBaseNamePath(tenantService), null)); + } + } nodeMetaData.setPaths(paths); @@ -1123,6 +1152,41 @@ public class SOLRTrackingComponentImpl implements SOLRTrackingComponent } } + private boolean isVersionNodeRef(NodeRef nodeRef) + { + return nodeRef.getStoreRef().getProtocol().equals(VersionModel.STORE_PROTOCOL) || nodeRef.getStoreRef().getIdentifier().equals(Version2Model.STORE_ID); + } + + @SuppressWarnings("deprecation") + protected NodeRef convertVersionNodeRefToVersionedNodeRef(NodeRef versionNodeRef) + { + Status status = nodeDAO.getNodeRefStatus(versionNodeRef); + if (status == null) + { + return versionNodeRef; + } + + Map properties = nodeDAO.getNodeProperties(status.getDbId()); + + NodeRef nodeRef = null; + + // Switch VersionStore depending on configured impl + if (versionNodeRef.getStoreRef().getIdentifier().equals(Version2Model.STORE_ID)) + { + // V2 version store (eg. workspace://version2Store) + nodeRef = (NodeRef)properties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF); + } + else if (versionNodeRef.getStoreRef().getIdentifier().equals(VersionModel.STORE_ID)) + { + // Deprecated V1 version store (eg. workspace://lightWeightVersionStore) + nodeRef = new NodeRef((String) properties.get(VersionModel.PROP_QNAME_FROZEN_NODE_STORE_PROTOCOL), + (String) properties.get(VersionModel.PROP_QNAME_FROZEN_NODE_STORE_ID), + (String) properties.get(VersionModel.PROP_QNAME_FROZEN_NODE_ID)); + } + + return nodeRef; + } + private QName getNodeType(Long nodeId) { QName result = nodeDAO.getNodeType(nodeId);