Merged V3.2E to HEAD

17571: ETHREEOH-1863 -  alfresco-webscript-framework.jar is not available in the alfresco-enterprise-sdk-3.1
          - although the framework jar was already part of the SDK when I looked I have done some re-organising of 
          - names and paths and added missing source files.    By no means finished but its another step forward.
   17581: Fix for ETHREEOH-3380 - upload servlet in Explorer does not handle well upload errors as no error message is displayed on the client browser.
   17582: ETHREEOH-2760 - Sealing of standard library root scope objects to prevent script potentially interfering with another scripts processing.
          - Example provided to fix ACT ticket issue against fixed codeline.
   17583: Fixed ETHREEOH-3458 "If the rss feed to display returns bad formatted data or is unavailable an ugly free marker error is displayed"
          - Rss urls pointing to a "missing resource"/"bad formated rss data" is now displayed as "Rss feed is unavailable"/"Can't read rss feed" (before they displayed freemarker error making it impossible to re-configure)
          - Title is now updated after config (therefore the change to return json instead of html) (before a page refresh was needed)
          - The new url is now updated in the "2nd" config dialog after it has been changed in the first (before page refresh was needed)
          - Removed un-internationalised string from config respons template
   17584: ALFCOM-3675 - WebDAV script does not allow inline editing for documents with name in upper case.
          - Now allows any case, as per supplied patch.
          - Also added support for Office 2007 file types so they can now be opened in write mode via webdav in IE6/7 from the Explorer client.
          - Tested in IE6/7.
   17585: Yet another fix for ETHREEOH-1733 - agenda view all days events fixed
   17586: ETHREEOH-1843:  /api/sites/*/memberships search is slow on specific query
   17587: Add cluster lock for JPBM job/timer executor (for WCM submits in a clustered env - ETHREEOH-2230 / ETHREEOH-3319)
   17590: New icons for View Original & View Working Copy actions
   17591: ETHREEOH-2879 - Alfresco + OpenLDAP: Unable to retrieve user from repository.
          - Fixed SURF to handle users without (utterly bizarely) First or Last names or even, usefully, neither.
   17592: Merged V3.2 to V3.1
      17415: Fix for ETHREEOH-3293 - Editing user details on large user repository causes Hibernate exception.
             Fix for ETHREEOH-3294 - Extreemly slow repository performance adding a new user to large user repository via the Explorer Client admin console.
   17593: Icon for doclib View In Browser action
   17594: ETHREEOH-2864 - Share - Documents cannot be deleted (in "All Documents" view)
   17595: ETHREEOH-3203:  Impossibility to add comment to any object by SiteContributor user
   17596: ETHREEOH-1469 - SMTP errors not reported when sending an invitation
            - now errors are reported.
            - may upset unit tests, i've fixed those I know about
   17598: Fixed ETHREEOH-3445 "Admin Console - Group Search sometimes never displays results list"
   17601: ETHREEOH-3382 - Share Sites menu is broken in "debug" mode. Reworked menu css. Removed unused footer component.
   17602: Share global debug flags removed from web-framework-config-application.xml. Use share-config-custom.xml instead.
   17603: Changed wording on Create/Edit Site dialogs from "Access" to "Visibility". "Access" was no longer accurate now that Moderated Sites' content is private to non-members.
   17604: ETHREEOH-1469 - SMTP error when sending an invitation does not return a failure.
          - SiteServiceTest also needed "fixing"
   17606: ETHREEOH-3475 - IE: Second search on add groups to site gets yui error but works. Related to YUI bug 2286608. YUI patched instead of all DataTable client code. (Patch removed from DocLib)
   17607: ETHREEOH-3470 - "Add" button is unavailable if the group with the name of more than 60 characters is found
   17608: Fixed invalid use of Forms validator. Validators updated to handle specific case anyway.
   17610: Fixed ETHREEOH-3445 "Admin Console - Group Search sometimes never displays results list" - missed commit of non-default theme files
   17612: Fixed ETHREEOH-3480 "Browse" button no longer works after Groups Admin console page is refreshed
   17613: ETHREEOH-3450 Fixed illegal nested comment in web-client-config-custom.xml.sample
   17616: Fix for ETHREEOH-2863 - Code cache memory leak observed in JVM 1.6 when script action calls another script which in turn calls other functions.
          - Fixed use of Rhino optimization level when executing string based scripts.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18160 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2010-01-20 10:22:18 +00:00
parent f89af49875
commit 2ab713d0cb
6 changed files with 305 additions and 63 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 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.workflow.jbpm;
import org.alfresco.repo.lock.JobLockService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log;
@@ -43,23 +44,32 @@ import org.springmodules.workflow.jbpm31.JbpmFactoryLocator;
public class AlfrescoJobExecutor extends JobExecutor
{
private static final long serialVersionUID = -4576396495395482111L;
private static Log log = LogFactory.getLog(JobExecutor.class);
private TransactionService transactionService;
private JbpmConfiguration jbpmConfiguration;
private JobLockService jobLockService;
private boolean jobExecutorLockEnabled = true;
public void setJobExecutorLockEnabled(boolean jobExecutorLockEnabled)
{
this.jobExecutorLockEnabled = jobExecutorLockEnabled;
}
/**
* Constructor
* Is Alfresco Job Executor Lock Enabled
*
* @return true if only one executor thread allowed (including across cluster)
*
* @since 3.2
*/
public AlfrescoJobExecutor()
public boolean getJobExecutorLockEnabled()
{
BeanFactoryLocator factoryLocator = new JbpmFactoryLocator();
BeanFactoryReference factory = factoryLocator.useBeanFactory(null);
transactionService = (TransactionService)factory.getFactory().getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
jbpmConfiguration = (JbpmConfiguration)factory.getFactory().getBean("jbpm_configuration");
return this.jobExecutorLockEnabled;
}
/**
* Gets Transaction Service
*
@@ -69,7 +79,34 @@ public class AlfrescoJobExecutor extends JobExecutor
{
return transactionService;
}
/**
* Gets Job Lock Service
*
* @return job lock service
*
* @since 3.2
*/
public JobLockService getJobLockService()
{
return jobLockService;
}
/**
* Constructor
*/
public AlfrescoJobExecutor()
{
BeanFactoryLocator factoryLocator = new JbpmFactoryLocator();
BeanFactoryReference factory = factoryLocator.useBeanFactory(null);
transactionService = (TransactionService)factory.getFactory().getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
jobLockService = (JobLockService)factory.getFactory().getBean(ServiceRegistry.JOB_LOCK_SERVICE.getLocalName());
jbpmConfiguration = (JbpmConfiguration)factory.getFactory().getBean("jbpm_configuration");
}
/* (non-Javadoc)
* @see org.jbpm.job.executor.JobExecutor#startThread()
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 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
@@ -28,8 +28,13 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import org.alfresco.repo.lock.LockAcquisitionException;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jbpm.JbpmConfiguration;
import org.jbpm.job.Job;
import org.jbpm.job.executor.JobExecutorThread;
@@ -38,13 +43,24 @@ import org.jbpm.job.executor.JobExecutorThread;
/**
* Alfresco Job Executor Thread
*
* @author davidc
* @author davidc, janv
*/
public class AlfrescoJobExecutorThread extends JobExecutorThread
{
/** The name of the lock used to ensure that job executor does not run on more than one node at the same time. */
private static final QName LOCK_QNAME = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI,
"AlfrescoJbpmJobExecutor");
private static Log logger = LogFactory.getLog(AlfrescoJobExecutorThread.class);
private AlfrescoJobExecutor alfrescoJobExecutor;
private boolean isActive = true;
private long jbpmMaxLockTime;
private long jobLockTTL = 0;
private String jobLockToken = null;
@Override
public void setActive(boolean isActive)
{
@@ -58,26 +74,75 @@ public class AlfrescoJobExecutorThread extends JobExecutorThread
{
super(name, jobExecutor, jbpmConfiguration, idleInterval, maxIdleInterval, maxLockTime, maxHistory);
this.alfrescoJobExecutor = jobExecutor;
this.jbpmMaxLockTime = maxLockTime;
this.jobLockTTL = jbpmMaxLockTime+(1000 * 60 * 10);
}
@SuppressWarnings("unchecked")
@Override
protected Collection acquireJobs()
{
if (!isActive)
Collection jobs = Collections.EMPTY_LIST;
if ((isActive) && (! alfrescoJobExecutor.getTransactionService().isReadOnly()))
{
return Collections.EMPTY_LIST;
}
else if (alfrescoJobExecutor.getTransactionService().isReadOnly())
{
return Collections.EMPTY_LIST;
}
return alfrescoJobExecutor.getTransactionService().getRetryingTransactionHelper().doInTransaction(
new RetryingTransactionHelper.RetryingTransactionCallback<Collection>() {
public Collection execute() throws Throwable
try
{
jobs = alfrescoJobExecutor.getTransactionService().getRetryingTransactionHelper().doInTransaction(
new RetryingTransactionHelper.RetryingTransactionCallback<Collection>() {
public Collection execute() throws Throwable
{
if (jobLockToken != null)
{
refreshExecutorLock(jobLockToken);
}
else
{
jobLockToken = getExecutorLock();
}
try
{
return AlfrescoJobExecutorThread.super.acquireJobs();
}
catch (Throwable t)
{
logger.error("Failed to acquire jobs");
releaseExecutorLock(jobLockToken);
jobLockToken = null;
throw t;
}
}
});
if (jobs != null)
{
return AlfrescoJobExecutorThread.super.acquireJobs();
if (logger.isDebugEnabled() && (! logger.isTraceEnabled()) && (! jobs.isEmpty()))
{
logger.debug("acquired "+jobs.size()+" job"+((jobs.size() != 1) ? "s" : ""));
}
if (logger.isTraceEnabled())
{
logger.trace("acquired "+jobs.size()+" job"+((jobs.size() != 1) ? "s" : "")+((jobs.size() > 0) ? ": "+jobs.toString() : ""));
}
if (jobs.size() == 0)
{
releaseExecutorLock(jobLockToken);
jobLockToken = null;
}
}
});
}
catch (LockAcquisitionException e)
{
// ignore
jobLockToken = null;
}
}
return jobs;
}
@Override
@@ -87,6 +152,7 @@ public class AlfrescoJobExecutorThread extends JobExecutorThread
{
return null;
}
return alfrescoJobExecutor.getTransactionService().getRetryingTransactionHelper().doInTransaction(
new RetryingTransactionHelper.RetryingTransactionCallback<Date>() {
public Date execute() throws Throwable
@@ -95,24 +161,104 @@ public class AlfrescoJobExecutorThread extends JobExecutorThread
}
}, true);
}
/**
* {@inheritDoc}
*/
@Override
protected void executeJob(Job job)
{
if (!isActive)
if ((!isActive) || (alfrescoJobExecutor.getTransactionService().isReadOnly()))
{
return;
}
else if (alfrescoJobExecutor.getTransactionService().isReadOnly())
try
{
return;
alfrescoJobExecutor.getTransactionService().getRetryingTransactionHelper().doInTransaction(new TransactionJob(job));
}
catch (LockAcquisitionException e)
{
// ignore
jobLockToken = null;
}
alfrescoJobExecutor.getTransactionService().getRetryingTransactionHelper().doInTransaction(new TransactionJob(job));
}
private String getExecutorLock()
{
String jobLockToken = null;
if (alfrescoJobExecutor.getJobExecutorLockEnabled())
{
try
{
jobLockToken = alfrescoJobExecutor.getJobLockService().getLock(LOCK_QNAME, jobLockTTL, 3000, 10);
if (logger.isTraceEnabled())
{
logger.trace(Thread.currentThread().getName()+" got lock token: "+jobLockToken);
}
}
catch (LockAcquisitionException e)
{
if (logger.isTraceEnabled())
{
logger.trace("Failed to get Alfresco Job Executor lock - may already running in another thread");
}
throw e;
}
}
return jobLockToken;
}
private void refreshExecutorLock(String jobLockToken)
{
if (jobLockToken != null)
{
try
{
alfrescoJobExecutor.getJobLockService().refreshLock(jobLockToken, LOCK_QNAME, jobLockTTL);
if (logger.isTraceEnabled())
{
logger.trace(Thread.currentThread().getName()+" refreshed lock token: "+jobLockToken);
}
}
catch (LockAcquisitionException e)
{
if (logger.isTraceEnabled())
{
logger.trace("Failed to refresh Alfresco Job Executor lock - may no longer exist ("+jobLockToken+")");
}
throw e;
}
}
}
private void releaseExecutorLock(String jobLockToken)
{
if (jobLockToken != null)
{
try
{
alfrescoJobExecutor.getJobLockService().releaseLock(jobLockToken, LOCK_QNAME);
if (logger.isTraceEnabled())
{
logger.trace(Thread.currentThread().getName()+" released lock token: "+jobLockToken);
}
}
catch (LockAcquisitionException e)
{
if (logger.isTraceEnabled())
{
logger.trace("Failed to release Alfresco Job Executor lock - may no longer exist ("+jobLockToken+")");
}
throw e;
}
}
}
/**
* Helper class for holding Job reference
@@ -122,7 +268,7 @@ public class AlfrescoJobExecutorThread extends JobExecutorThread
private class TransactionJob implements RetryingTransactionCallback<Object>
{
private Job job;
/**
* Constructor
*
@@ -132,13 +278,19 @@ public class AlfrescoJobExecutorThread extends JobExecutorThread
{
this.job = job;
}
public Object execute() throws Throwable
{
refreshExecutorLock(jobLockToken);
AlfrescoJobExecutorThread.super.executeJob(job);
if (logger.isDebugEnabled())
{
logger.debug("executed job: "+job);
}
return null;
}
}
}