Merged V3.4-BUG-FIX to HEAD

32456: (RECORD ONLY) Removed extraneous debugging
   32538: ALF-12075: Merged DEV/TEMPORARY to V3.4-BUG-FIX
      32476: ALF-11499: "The association source type is incorrect: " when trying to add extra documents to inflight workflow after upgrade to 3.2.0r and later
         Patch that converts workflow package type and associations
      32532: ALF-11499: "The association source type is incorrect: " when trying to add extra documents to inflight workflow after upgrade to 3.2.0r and later
         1. Code comments
         2. Removed potential catch of retryable exception
         3. Removed unneccessary throw of PatchException   
   32541: Fix for ALF-11677 - Doing an HTTP POST to a repository webscript through the Share proxy fails on certain input
   32712: ALF-12074 / ALF-10547: JMX settings lost after upgrade from 3.2.2 to 3.4.4
   - MigrateAttrPropBackedBeanPatch now persists migrated data through the MBean interfaces (cluster and cache friendly) rather than going through the 'back door'
   32734: ALF-12076: Fix ALF-11924 - HighlightFile after document upload in Share doclib
   32738: ALF-11957: Merged PATCHES/V3.4.6 to V3.4-BUG-FIX
      32617: ALF-11977 / ALF-11879: IMAP performance
      - Fix node batch loading - batch load ContentData to avoid N+1 problem with content properties
      - During cache preloading, use distinct transactions for each folder search, thus avoiding blowing the transactional caches
      32619: ALF-11977 / ALF-11879: Fixed typo
      32652: ALF-11977 / ALF-11879: Deactivate auto-versioning and auditing (and run as system) whilst setting magic IMAP aspect properties
      32683: ALF-11978 / ALF-11915 iBatis synchronizes on the ClassInfo class during high concurrency
         Similar change made to ibatis ClassInfo.java as was made to mybatis (in 4.0) for ALF-11894
         src.diff is diff from new SVN location at http://mybatis.googlecode.com/svn/tags/java_release_2.3.4-726/ibatis-2-core hence the revision number changes
         modified the pom to use Java 1.5 (1.6 does not work due to changes in abstract sql packages) and removed a plugin that no longer works   
   32788: ALF-12077: Fix for ALF-12050 - ensures that overly agressive caches won't cache Share PageView dynamic responses.
   32818: Merged PATCHES/V3.4.6 to V3.4-BUG-FIX
      32510: (RECORD ONLY) Merged V3.4-BUG-FIX to PATCHES/V3.4.6
         32322: Possible fix for: (ALF-11344) SORT clause in CMIS query (ORDER BY) drastically affects performance of search.
            - English based locales will sort as Java String comparison.
         32411: Fix for ALF-11344 SORT clause in CMIS query (ORDER BY) drastically affects performance of search.
            - use in memory sort rather than relying on the lucene field cache for result sets up to 1000 by default 
            - this is configurable across all query languages (and per query via SearchParameters and QueryOptions)
                 lucene.indexer.useInMemorySort=true
                 lucene.indexer.maxRawResultSetSizeForInMemorySort=1000
         32425: Fix for ALF-11344 SORT clause in CMIS query (ORDER BY) drastically affects performance of search.
            - fix for score sorting   
      32616: (RECORD ONLY) ALF-11849: Merged V3.4-BUG-FIX to PATCHES/V3.4.6
         31653: ALF-8906: Ensure entire IMAP service startup transaction runs as system, to allow for any auto-aspect adding / versioning during cache warming
         31676: ALF-8906: Fix IMAP unit test failures   
      32792: ALF-11894 / ALF-11915: Prevent contention in NodeService proxy by making NodeService_security proxy to a thread local!
      - Use org.springframework.aop.target.ThreadLocalTargetSource
      - Inventive or what?
      32814: ALF-11894 / ALF-11915: Prevent contention in CMIS searches
      - Rolled back previous fix because it didn't work!
      - Patched ACEGI ConfigAttributeDefinition to use LinkedList rather than synchronized Vector to avoid contention on all NodeService accesses
      - Created NonBlockingLazyInitTargetSource, again to avoid contention on all NodeService calls   
      32816: (RECORD ONLY) ALF-12072: Merged V3.4-BUG-FIX to PATCHES/V3.4.6
         32788: Fix for ALF-12050 - ensures that overly aggressive caches won't cache Share PageView dynamic responses.
   32819: Merged V3.4 to V3.4-BUG-FIX (RECORD ONLY)
      32817: Merged PATCHES/V3.4.6 to V3.4 (3.4.7)
         32510: ALF-11840: Merged V3.4-BUG-FIX to PATCHES/V3.4.6
            32322: Possible fix for: (ALF-11344) SORT clause in CMIS query (ORDER BY) drastically affects performance of search.
               - English based locales will sort as Java String comparison.
            32411: Fix for ALF-11344 SORT clause in CMIS query (ORDER BY) drastically affects performance of search.
               - use in memory sort rather than relying on the lucene field cache for result sets up to 1000 by default 
               - this is configurable across all query languages (and per query via SearchParameters and QueryOptions)
                    lucene.indexer.useInMemorySort=true
                    lucene.indexer.maxRawResultSetSizeForInMemorySort=1000
            32425: Fix for ALF-11344 SORT clause in CMIS query (ORDER BY) drastically affects performance of search.
               - fix for score sorting   
         32792: ALF-11978 / ALF-11915: Prevent contention in NodeService proxy by making NodeService_security proxy to a thread local!
            - Use org.springframework.aop.target.ThreadLocalTargetSource
            - Inventive or what?
         32814: ALF-11978 / ALF-11915: Prevent contention in CMIS searches
            - Rolled back previous fix because it didn't work!
            - Patched ACEGI ConfigAttributeDefinition to use LinkedList rather than synchronized Vector to avoid contention on all NodeService accesses
            - Created NonBlockingLazyInitTargetSource, again to avoid contention on all NodeService calls   
         32816: ALF-12050: Merged V3.4-BUG-FIX to PATCHES/V3.4.6
            32788: Fix for ALF-12050 - ensures that overly aggressive caches won't cache Share PageView dynamic responses.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@32821 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2011-12-16 15:38:35 +00:00
parent 9b458b3655
commit aac8f44c59
6 changed files with 262 additions and 8 deletions

View File

@@ -449,4 +449,9 @@ patch.updateFollowingEmailTemplatesPatch.error=Error retrieving base template wh
patch.addDutchEmailTemplatesPatch.description=Patch to add Dutch email templates. patch.addDutchEmailTemplatesPatch.description=Patch to add Dutch email templates.
patch.addDutchEmailTemplatesPatch.result=Dutch email templates have been successfully added. patch.addDutchEmailTemplatesPatch.result=Dutch email templates have been successfully added.
patch.addDutchEmailTemplatesPatch.error=Error retrieving base template when trying to add Dutch email templates. patch.addDutchEmailTemplatesPatch.error=Error retrieving base template when trying to add Dutch email templates.
patch.fixBpmPackages.description=Corrects workflow package types and associations
patch.fixBpmPackages.result=Patch successful. {0} packages converted.
patch.fixBpmPackages.invalidBootsrapStore=Bootstrap store has not been set
patch.fixBpmPackages.emptyContainer={0} node has no children

View File

@@ -2966,7 +2966,7 @@
<value>true</value> <value>true</value>
</property> </property>
</bean> </bean>
<bean id="patch.updateFollowingEmailTemplatesPatch" class="org.alfresco.repo.admin.patch.impl.UpdateFollowingEmailTemplatesPatch" parent="basePatch"> <bean id="patch.updateFollowingEmailTemplatesPatch" class="org.alfresco.repo.admin.patch.impl.UpdateFollowingEmailTemplatesPatch" parent="basePatch">
<property name="id"><value>patch.updateFollowingEmailTemplatesPatch</value></property> <property name="id"><value>patch.updateFollowingEmailTemplatesPatch</value></property>
<property name="description"><value>patch.updateFollowingEmailTemplatesPatch.description</value></property> <property name="description"><value>patch.updateFollowingEmailTemplatesPatch.description</value></property>
@@ -3004,4 +3004,15 @@
<property name="repository" ref="repositoryHelper"/> <property name="repository" ref="repositoryHelper"/>
</bean> </bean>
<bean id="patch.fixBpmPackages" class="org.alfresco.repo.admin.patch.impl.FixBpmPackagesPatch" parent="basePatch">
<property name="id"><value>patch.fixBpmPackages</value></property>
<property name="description"><value>patch.fixBpmPackages.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>5024</value></property>
<property name="targetSchema"><value>5025</value></property>
<property name="importerBootstrap">
<ref bean="spacesBootstrap" />
</property>
</bean>
</beans> </beans>

View File

@@ -68,7 +68,7 @@
</property> </property>
<!-- Lazy init to avoid circular dependencies --> <!-- Lazy init to avoid circular dependencies -->
<property name="targetSource"> <property name="targetSource">
<bean class="org.springframework.aop.target.LazyInitTargetSource"> <bean class="org.alfresco.config.NonBlockingLazyInitTargetSource">
<property name="targetBeanName"> <property name="targetBeanName">
<idref bean="nodeService" /> <idref bean="nodeService" />
</property> </property>

View File

@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number # Schema number
version.schema=5024 version.schema=5025

View File

@@ -0,0 +1,173 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Patch that updates workflow package type and package items associations
*
* @see https://issues.alfresco.com/jira/browse/ETHREEOH-3613
* @see https://issues.alfresco.com/jira/browse/ALF-11499
* @author Arseny Kovalchuk
* @since 3.4.7
*/
public class FixBpmPackagesPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.fixBpmPackages.result";
private static final String ERR_MSG_INVALID_BOOTSTRAP_STORE = "patch.fixBpmPackages.invalidBootsrapStore";
private static final String ERR_MSG_EMPTY_CONTAINER = "patch.fixBpmPackages.emptyContainer";
private static final Log logger = LogFactory.getLog(FixBpmPackagesPatch.class);
private ImporterBootstrap importerBootstrap;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
@Override
protected String applyInternal() throws Exception
{
// Package counter for report
int packagesCount = 0;
StoreRef store = importerBootstrap.getStoreRef();
if (store == null)
{
throw new PatchException(ERR_MSG_INVALID_BOOTSTRAP_STORE);
}
// Get root node for store
NodeRef rootRef = nodeService.getRootNode(store);
if (logger.isDebugEnabled())
logger.debug("StoreRef:" + store + " RootNodeRef: " + rootRef);
// Get /sys:system container path, if it doesn't exist there is something wrong with the repo
String sysContainer = importerBootstrap.getConfiguration().getProperty("system.system_container.childname");
QName sysContainerQName = QName.createQName(sysContainer, namespaceService);
List<ChildAssociationRef> refs = nodeService.getChildAssocs(rootRef, ContentModel.ASSOC_CHILDREN, sysContainerQName);
if (refs == null || refs.size() == 0)
throw new PatchException(ERR_MSG_EMPTY_CONTAINER, sysContainer);
NodeRef sysNodeRef = refs.get(0).getChildRef();
// Get /sys:system/sys:workflow container, if it doesn't exist there is something wrong with the repo
String sysWorkflowContainer = importerBootstrap.getConfiguration().getProperty("system.workflow_container.childname");
QName sysWorkflowQName = QName.createQName(sysWorkflowContainer, namespaceService);
refs = nodeService.getChildAssocs(sysNodeRef, ContentModel.ASSOC_CHILDREN, sysWorkflowQName);
if (refs == null || refs.size() == 0)
throw new PatchException(ERR_MSG_EMPTY_CONTAINER, sysWorkflowContainer);
NodeRef workflowContainerRef = refs.get(0).getChildRef();
// Try to get /sys:system/sys:workflow/cm:packages, if there is no such node, then it wasn't created yet,
// so there is nothing to convert
refs = nodeService.getChildAssocs(workflowContainerRef, ContentModel.ASSOC_CHILDREN, RegexQNamePattern.MATCH_ALL);
if (refs == null || refs.size() == 0)
{
if (logger.isDebugEnabled())
logger.debug("There are no any packages in the container " + sysWorkflowContainer);
return I18NUtil.getMessage(MSG_SUCCESS, packagesCount);
}
// Get /sys:system/sys:workflow/cm:packages container NodeRef
NodeRef packagesContainerRef = refs.get(0).getChildRef();
// Get workflow packages to be converted
refs = nodeService.getChildAssocs(packagesContainerRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
if (logger.isDebugEnabled())
logger.debug("Found " + refs.size() + " packages to convert");
NodeRef packageRef = null;
// For each package we get package items and convert their type from cm:systemfolder to bpm:package
// Also we convert associations between packages and their items from cm:contains to bpm:packageContains
for (ChildAssociationRef assocRef : refs)
{
packageRef = assocRef.getChildRef();
QName typeQname = nodeService.getType(packageRef);
String name = (String) nodeService.getProperty(packageRef, ContentModel.PROP_NAME);
if (logger.isDebugEnabled())
logger.debug("Package " + name + " type " + typeQname);
// New type of the package is bpm:package
nodeService.setType(packageRef, WorkflowModel.TYPE_PACKAGE);
// Get all package items
List<ChildAssociationRef> packageItemsAssocs = nodeService.getChildAssocs(packageRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef itemAssoc : packageItemsAssocs)
{
NodeRef parentRef = itemAssoc.getParentRef();
NodeRef childRef = itemAssoc.getChildRef();
String itemName = (String) nodeService.getProperty(childRef, ContentModel.PROP_NAME);
// To avoid unnecessary deletion of the child item, we check if the association is not primary
// For the package item it should be not primary association.
if (itemAssoc.isPrimary())
{
logger.error("Association between package: " + name + " and item: " + itemName + " is primary association, so removing this assiciation will result in child node deletion");
continue;
}
boolean assocRemoved = nodeService.removeChildAssociation(itemAssoc);
if (assocRemoved)
{
if (logger.isDebugEnabled())
logger.debug("Association between package: " + name + " and item: " + itemName + " was removed");
}
else
{
if (logger.isErrorEnabled())
logger.error("Association between package: " + name + " and item: " + itemName + " doesn't exist");
// If there is no association we won't create a new one
continue;
}
// Recreate new association between package and particular item as bpm:packageContains
/* ChildAssociationRef newChildAssoc = */nodeService.addChild(parentRef, childRef, WorkflowModel.ASSOC_PACKAGE_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(itemName)));
if (logger.isDebugEnabled())
{
logger.debug("New association has been created between package: " + name + " and item: " + itemName);
}
}
packagesCount++;
}
return I18NUtil.getMessage(MSG_SUCCESS, packagesCount);
}
}

View File

@@ -19,9 +19,15 @@
package org.alfresco.repo.admin.patch.impl; package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable; import java.io.Serializable;
import java.net.URLDecoder;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import org.alfresco.repo.admin.patch.AbstractPatch; import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.domain.patch.PatchDAO; import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.service.cmr.attributes.AttributeService; import org.alfresco.service.cmr.attributes.AttributeService;
@@ -29,6 +35,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.ResultHandler;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.extensions.surf.util.I18NUtil; import org.springframework.extensions.surf.util.I18NUtil;
/** /**
@@ -37,7 +46,7 @@ import org.springframework.extensions.surf.util.I18NUtil;
* @author janv * @author janv
* @since 3.4 * @since 3.4
*/ */
public class MigrateAttrPropBackedBeanPatch extends AbstractPatch public class MigrateAttrPropBackedBeanPatch extends AbstractPatch implements ApplicationContextAware
{ {
private Log logger = LogFactory.getLog(this.getClass()); private Log logger = LogFactory.getLog(this.getClass());
@@ -47,6 +56,7 @@ public class MigrateAttrPropBackedBeanPatch extends AbstractPatch
private AttributeService attributeService; private AttributeService attributeService;
private PatchDAO patchDAO; private PatchDAO patchDAO;
private MBeanServerConnection mbeanServer;
public void setAttributeService(AttributeService attributeService) public void setAttributeService(AttributeService attributeService)
{ {
@@ -58,6 +68,16 @@ public class MigrateAttrPropBackedBeanPatch extends AbstractPatch
this.patchDAO = patchDAO; this.patchDAO = patchDAO;
} }
/* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
// Optional dependency - may not exist in community builds
this.mbeanServer = (MBeanServerConnection) applicationContext.getBean("alfrescoMBeanServer");
}
@Override @Override
protected String applyInternal() throws Exception protected String applyInternal() throws Exception
{ {
@@ -124,10 +144,55 @@ public class MigrateAttrPropBackedBeanPatch extends AbstractPatch
{ {
return; return;
} }
attributeService.setAttribute(
(Serializable) attributeMap,
ROOT_KEY_PBB, componentName);
boolean done = false;
try
{
// Go through the subsystem MBean interface in case the subsystem is already live and the cluster needs
// to be resynced
// Decode the bean ID to a hierarchical object name
String[] components = componentName.split("\\$");
StringBuilder nameBuff = new StringBuilder(200).append("Alfresco:Type=Configuration,Category=").append(
URLDecoder.decode(components[0], "UTF-8"));
for (int i = 1; i < components.length; i++)
{
nameBuff.append(",id").append(i).append('=').append(URLDecoder.decode(components[i], "UTF-8"));
}
ObjectName name = new ObjectName(nameBuff.toString());
if (mbeanServer != null && mbeanServer.isRegistered(name))
{
AttributeList attributeList = new AttributeList();
for (Map.Entry<String, String> entry : attributeMap.entrySet())
{
attributeList.add(new Attribute(entry.getKey(), entry.getValue()));
}
mbeanServer.setAttributes(name, attributeList);
// We've successfully persisted the attributes. Job done
done = true;
}
}
catch (Exception e)
{
if (logger.isWarnEnabled())
{
logger
.warn(
"Exception migrating attributes of subsystem "
+ componentName
+ ". Falling back to repository-only operation. Subsystem may remain out of sync until reboot.",
e);
}
}
// Fallback: perhaps the subsystem isn't up yet and hasn't exported its bean. Or perhaps an error occurred
// above. Let's persist the new property anyway.
if (!done)
{
attributeService.setAttribute((Serializable) attributeMap, ROOT_KEY_PBB, componentName);
}
if (logger.isTraceEnabled()) if (logger.isTraceEnabled())
{ {
logger.trace("Set PBB component attr [name="+componentName+", attributeMap="+attributeMap+"]"); logger.trace("Set PBB component attr [name="+componentName+", attributeMap="+attributeMap+"]");