mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-273 - RM: PublishUpdatesJob allows concurrent execution
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0@36435 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -10,29 +10,27 @@
|
|||||||
-->
|
-->
|
||||||
<bean id="scheduledNotifyOfRecordsDueForReviewJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
<bean id="scheduledNotifyOfRecordsDueForReviewJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
||||||
<property name="jobClass">
|
<property name="jobClass">
|
||||||
<value>org.alfresco.module.org_alfresco_module_rm.job.NotifyOfRecordsDueForReviewJob</value>
|
<value>org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJob</value>
|
||||||
</property>
|
</property>
|
||||||
<property name="jobDataAsMap">
|
<property name="jobDataAsMap">
|
||||||
<map>
|
<map>
|
||||||
<entry key="recordsManagementService">
|
<entry key="jobName" value="scheduledNotifyOfRecordsDueForReview"/>
|
||||||
<ref bean="recordsManagementService"/>
|
<entry key="jobLockService">
|
||||||
|
<ref bean="jobLockService" />
|
||||||
</entry>
|
</entry>
|
||||||
<entry key="recordsManagementNotificationHelper">
|
<entry key="jobExecuter">
|
||||||
<ref bean="recordsManagementNotificationHelper"/>
|
<ref bean="scheduledNotifyOfRecordsDueForReviewJobExecuter" />
|
||||||
</entry>
|
|
||||||
<entry key="nodeService">
|
|
||||||
<ref bean="nodeService" />
|
|
||||||
</entry>
|
|
||||||
<entry key="searchService">
|
|
||||||
<ref bean="searchService" />
|
|
||||||
</entry>
|
|
||||||
<entry key="transactionService">
|
|
||||||
<ref bean="transactionService" />
|
|
||||||
</entry>
|
</entry>
|
||||||
</map>
|
</map>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="scheduledNotifyOfRecordsDueForReviewJobExecuter" class="org.alfresco.module.org_alfresco_module_rm.job.NotifyOfRecordsDueForReviewJobExecuter">
|
||||||
|
<property name="nodeService" ref="nodeService" />
|
||||||
|
<property name="searchService" ref="searchService" />
|
||||||
|
<property name="recordsManagementNotificationHelper" ref="recordsManagementNotificationHelper" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="scheduledNotifyOfRecordsDueForReviewJobTrigger" class="org.alfresco.util.CronTriggerBean">
|
<bean id="scheduledNotifyOfRecordsDueForReviewJobTrigger" class="org.alfresco.util.CronTriggerBean">
|
||||||
<property name="jobDetail">
|
<property name="jobDetail">
|
||||||
<ref bean="scheduledNotifyOfRecordsDueForReviewJobDetail" />
|
<ref bean="scheduledNotifyOfRecordsDueForReviewJobDetail" />
|
||||||
@@ -49,26 +47,28 @@
|
|||||||
<!-- Disposition Lifecycle Job -->
|
<!-- Disposition Lifecycle Job -->
|
||||||
<bean id="scheduledDispositionLifecyceleJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
<bean id="scheduledDispositionLifecyceleJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
||||||
<property name="jobClass">
|
<property name="jobClass">
|
||||||
<value>org.alfresco.module.org_alfresco_module_rm.job.DispositionLifecycleJob</value>
|
<value>org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJob</value>
|
||||||
</property>
|
</property>
|
||||||
<property name="jobDataAsMap">
|
<property name="jobDataAsMap">
|
||||||
<map>
|
<map>
|
||||||
<entry key="nodeService">
|
<entry key="jobName" value="dispositionLifecycle"/>
|
||||||
<ref bean="nodeService" />
|
<entry key="jobLockService">
|
||||||
|
<ref bean="jobLockService" />
|
||||||
</entry>
|
</entry>
|
||||||
<entry key="searchService">
|
<entry key="jobExecuter">
|
||||||
<ref bean="searchService" />
|
<ref bean="dispositionLifecycleJobExecuter" />
|
||||||
</entry>
|
|
||||||
<entry key="recordsManagementActionService">
|
|
||||||
<ref bean="recordsManagementActionService" />
|
|
||||||
</entry>
|
|
||||||
<entry key="transactionService">
|
|
||||||
<ref bean="transactionService" />
|
|
||||||
</entry>
|
</entry>
|
||||||
</map>
|
</map>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="dispositionLifecycleJobExecuter" class="org.alfresco.module.org_alfresco_module_rm.job.DispositionLifecycleJobExecuter">
|
||||||
|
<property name="nodeService" ref="nodeService" />
|
||||||
|
<property name="searchService" ref="searchService" />
|
||||||
|
<property name="retryingTransactionHelper" ref="retryingTransactionHelper" />
|
||||||
|
<property name="recordsManagementActionService" ref="recordsManagementActionService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="scheduledDispositionLifecyceleJobTrigger" class="org.alfresco.util.CronTriggerBean">
|
<bean id="scheduledDispositionLifecyceleJobTrigger" class="org.alfresco.util.CronTriggerBean">
|
||||||
<property name="jobDetail">
|
<property name="jobDetail">
|
||||||
<ref bean="scheduledDispositionLifecyceleJobDetail" />
|
<ref bean="scheduledDispositionLifecyceleJobDetail" />
|
||||||
@@ -84,42 +84,38 @@
|
|||||||
|
|
||||||
<bean id="scheduledPublishUpdatesJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
<bean id="scheduledPublishUpdatesJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
||||||
<property name="jobClass">
|
<property name="jobClass">
|
||||||
<value>org.alfresco.module.org_alfresco_module_rm.job.PublishUpdatesJob</value>
|
<value>org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJob</value>
|
||||||
</property>
|
</property>
|
||||||
<property name="jobDataAsMap">
|
<property name="jobDataAsMap">
|
||||||
<map>
|
<map>
|
||||||
<entry key="nodeService">
|
<entry key="jobName" value="publishUpdates"/>
|
||||||
<ref bean="nodeService" />
|
<entry key="jobLockService">
|
||||||
|
<ref bean="jobLockService" />
|
||||||
</entry>
|
</entry>
|
||||||
<entry key="searchService">
|
<entry key="jobExecuter">
|
||||||
<ref bean="searchService" />
|
<ref bean="publishUpdatesJobExecuter" />
|
||||||
</entry>
|
|
||||||
<entry key="retryingTransactionHelper">
|
|
||||||
<ref bean="retryingTransactionHelper" />
|
|
||||||
</entry>
|
|
||||||
<entry key="publishExecutorRegistry">
|
|
||||||
<ref bean="publishExecutorRegistry" />
|
|
||||||
</entry>
|
|
||||||
<entry key="behaviourFilter">
|
|
||||||
<ref bean="policyBehaviourFilter" />
|
|
||||||
</entry>
|
</entry>
|
||||||
</map>
|
</map>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="scheduledPublishUpdatesJobTrigger" class="org.alfresco.util.CronTriggerBean">
|
<bean id="scheduledPublishUpdatesJobTrigger" class="org.alfresco.util.CronTriggerBean">
|
||||||
<property name="jobDetail">
|
<property name="jobDetail" ref="scheduledPublishUpdatesJobDetail" />
|
||||||
<ref bean="scheduledPublishUpdatesJobDetail" />
|
<property name="scheduler" ref="schedulerFactory" />
|
||||||
</property>
|
|
||||||
<property name="scheduler">
|
|
||||||
<ref bean="schedulerFactory" />
|
|
||||||
</property>
|
|
||||||
<property name="cronExpression">
|
<property name="cronExpression">
|
||||||
<!-- <value>0 30 3 * * ?</value> -->
|
<!-- <value>0 30 3 * * ?</value> -->
|
||||||
<value>0/30 * * * * ?</value>
|
<value>0/30 * * * * ?</value>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="publishUpdatesJobExecuter" class="org.alfresco.module.org_alfresco_module_rm.job.PublishUpdatesJobExecuter">
|
||||||
|
<property name="nodeService" ref="nodeService" />
|
||||||
|
<property name="searchService" ref="searchService" />
|
||||||
|
<property name="retryingTransactionHelper" ref="retryingTransactionHelper" />
|
||||||
|
<property name="publishExecutorRegistry" ref="publishExecutorRegistry" />
|
||||||
|
<property name="behaviourFilter" ref="policyBehaviourFilter" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="publishExecutorRegistry" class="org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutorRegistry"/>
|
<bean id="publishExecutorRegistry" class="org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutorRegistry"/>
|
||||||
|
|
||||||
<bean id="dispositionActionDefintionPublishExecutor"
|
<bean id="dispositionActionDefintionPublishExecutor"
|
||||||
|
@@ -87,12 +87,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="rmEntryVoter" class="org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoter" lazy-init="false" parent="RMSecurityCommon">
|
<bean id="rmEntryVoter"
|
||||||
|
class="org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoter"
|
||||||
|
lazy-init="false"
|
||||||
|
parent="RMSecurityCommon"
|
||||||
|
depends-on="CapabilityService">
|
||||||
<!-- Services -->
|
<!-- Services -->
|
||||||
<property name="namespacePrefixResolver" ref="namespaceService"/>
|
<property name="namespacePrefixResolver" ref="namespaceService"/>
|
||||||
<property name="dictionaryService" ref="dictionaryService"/>
|
<property name="dictionaryService" ref="dictionaryService"/>
|
||||||
<property name="dispositionService" ref="dispositionService"/>
|
<property name="dispositionService" ref="dispositionService"/>
|
||||||
<property name="capabilityService" ref="CapabilityService"/>
|
<property name="capabilityService" ref="capabilityService"/>
|
||||||
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
@@ -229,10 +229,9 @@
|
|||||||
|
|
||||||
<!-- Capability Service -->
|
<!-- Capability Service -->
|
||||||
|
|
||||||
<bean id="CapabilityService" class="org.alfresco.module.org_alfresco_module_rm.capability.CapabilityServiceImpl">
|
<bean id="capabilityService" class="org.alfresco.module.org_alfresco_module_rm.capability.CapabilityServiceImpl">
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!--
|
|
||||||
<bean id="CapabilityService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
<bean id="CapabilityService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||||
<property name="proxyInterfaces">
|
<property name="proxyInterfaces">
|
||||||
<value>org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService</value>
|
<value>org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService</value>
|
||||||
@@ -244,7 +243,7 @@
|
|||||||
<list>
|
<list>
|
||||||
<idref local="CapabilityService_transaction"/>
|
<idref local="CapabilityService_transaction"/>
|
||||||
<idref bean="exceptionTranslator"/>
|
<idref bean="exceptionTranslator"/>
|
||||||
<idref local="CapabilityService_security"/>
|
<!-- <idref local="CapabilityService_security"/> -->
|
||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -273,15 +272,11 @@
|
|||||||
<property name="objectDefinitionSource">
|
<property name="objectDefinitionSource">
|
||||||
<value>
|
<value>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService.registerCapability=RM_ALLOW
|
org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService.*=RM_ALLOW
|
||||||
org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService.getCapability=RM_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService.getCapabilities=RM_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService.getCapabilitiesAccessState=RM_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService.*=RM_DENY
|
|
||||||
]]>
|
]]>
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
</bean> -->
|
</bean>
|
||||||
|
|
||||||
<!-- Records Management Search Service -->
|
<!-- Records Management Search Service -->
|
||||||
|
|
||||||
|
@@ -49,21 +49,24 @@ public interface CapabilityService
|
|||||||
Capability getCapability(String name);
|
Capability getCapability(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get a list of all the assignable capabilities.
|
||||||
*
|
*
|
||||||
* @return
|
* @return {@link Set}<{@link Capability}> set of all the assignable capabilities
|
||||||
*/
|
*/
|
||||||
Set<Capability> getCapabilities();
|
Set<Capability> getCapabilities();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get a list of all the capabilities, optionally including those that are non-assignable.
|
||||||
*
|
*
|
||||||
* @param includePrivate
|
* @param includePrivate indicates that the private, or non-assignable capabilities are included in the result
|
||||||
* @return
|
* @return {@link Set}<{@link Capability}> set of capabilities
|
||||||
*/
|
*/
|
||||||
Set<Capability> getCapabilities(boolean includePrivate);
|
Set<Capability> getCapabilities(boolean includePrivate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get all the capabilities access state based on the current user.
|
||||||
*
|
*
|
||||||
* @param nodeRef
|
* @param nodeRef node reference
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Map<Capability, AccessStatus> getCapabilitiesAccessState(NodeRef nodeRef);
|
Map<Capability, AccessStatus> getCapabilitiesAccessState(NodeRef nodeRef);
|
||||||
|
@@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009-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.module.org_alfresco_module_rm.job;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
|
||||||
import org.alfresco.service.cmr.search.ResultSet;
|
|
||||||
import org.alfresco.service.cmr.search.SearchService;
|
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.quartz.Job;
|
|
||||||
import org.quartz.JobExecutionContext;
|
|
||||||
import org.quartz.JobExecutionException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Disposition Lifecycle Job Finds all disposition action nodes which are
|
|
||||||
* for "retain" or "cutOff" actions Where asOf > now OR
|
|
||||||
* dispositionEventsEligible = true;
|
|
||||||
*
|
|
||||||
* Runs the cut off or retain action for
|
|
||||||
* elligible records.
|
|
||||||
*
|
|
||||||
* @author mrogers
|
|
||||||
*/
|
|
||||||
public class DispositionLifecycleJob implements Job
|
|
||||||
{
|
|
||||||
private static Log logger = LogFactory.getLog(DispositionLifecycleJob.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
|
|
||||||
*/
|
|
||||||
public void execute(JobExecutionContext context) throws JobExecutionException
|
|
||||||
{
|
|
||||||
final RecordsManagementActionService rmActionService = (RecordsManagementActionService) context
|
|
||||||
.getJobDetail().getJobDataMap().get("recordsManagementActionService");
|
|
||||||
final NodeService nodeService = (NodeService) context.getJobDetail().getJobDataMap().get(
|
|
||||||
"nodeService");
|
|
||||||
final SearchService search = (SearchService) context.getJobDetail().getJobDataMap().get(
|
|
||||||
"searchService");
|
|
||||||
final TransactionService trxService = (TransactionService) context.getJobDetail()
|
|
||||||
.getJobDataMap().get("transactionService");
|
|
||||||
|
|
||||||
logger.debug("Job Starting");
|
|
||||||
|
|
||||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
|
||||||
{
|
|
||||||
public Object doWork() throws Exception
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("+TYPE:\"rma:dispositionAction\" ");
|
|
||||||
sb.append("+(@rma\\:dispositionAction:(\"cutoff\" OR \"retain\"))");
|
|
||||||
sb.append("+ISNULL:\"rma:dispositionActionCompletedAt\" ");
|
|
||||||
sb.append("+( ");
|
|
||||||
sb.append("@rma\\:dispositionEventsEligible:true ");
|
|
||||||
sb.append("OR @rma\\:dispositionAsOf:[MIN TO NOW] ");
|
|
||||||
sb.append(") ");
|
|
||||||
|
|
||||||
String query = sb.toString();
|
|
||||||
|
|
||||||
ResultSet results = search.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,
|
|
||||||
SearchService.LANGUAGE_LUCENE, query);
|
|
||||||
List<NodeRef> resultNodes = results.getNodeRefs();
|
|
||||||
results.close();
|
|
||||||
|
|
||||||
RetryingTransactionHelper trn = trxService.getRetryingTransactionHelper();
|
|
||||||
|
|
||||||
for (NodeRef node : resultNodes)
|
|
||||||
{
|
|
||||||
final NodeRef currentNode = node;
|
|
||||||
|
|
||||||
RetryingTransactionCallback<Boolean> processTranCB = new RetryingTransactionCallback<Boolean>()
|
|
||||||
{
|
|
||||||
public Boolean execute() throws Throwable
|
|
||||||
{
|
|
||||||
final String dispAction = (String) nodeService.getProperty(currentNode,
|
|
||||||
RecordsManagementModel.PROP_DISPOSITION_ACTION);
|
|
||||||
|
|
||||||
// Run "retain" and "cutoff" actions.
|
|
||||||
|
|
||||||
if (dispAction != null)
|
|
||||||
{
|
|
||||||
if (dispAction.equalsIgnoreCase("cutoff") ||
|
|
||||||
dispAction.equalsIgnoreCase("retain"))
|
|
||||||
{
|
|
||||||
ChildAssociationRef parent = nodeService.getPrimaryParent(currentNode);
|
|
||||||
if (parent.getTypeQName().equals(RecordsManagementModel.ASSOC_NEXT_DISPOSITION_ACTION))
|
|
||||||
{
|
|
||||||
// Check that the action is executable
|
|
||||||
RecordsManagementAction rmAction = rmActionService.getDispositionAction(dispAction);
|
|
||||||
if (rmAction.isExecutable(parent.getParentRef(), null) == true)
|
|
||||||
{
|
|
||||||
rmActionService.executeRecordsManagementAction(parent.getParentRef(), dispAction);
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
logger.debug("Processed action: " + dispAction + "on" + parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.debug("The disposition action " + dispAction + " is not executable.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Boolean.TRUE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Now do the work, one action in each transaction
|
|
||||||
*/
|
|
||||||
trn.doInTransaction(processTranCB);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
|
||||||
|
|
||||||
logger.debug("Job Finished");
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009-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.module.org_alfresco_module_rm.job;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.ResultSet;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Disposition Lifecycle Job Finds all disposition action nodes which are
|
||||||
|
* for "retain" or "cutOff" actions Where asOf > now OR
|
||||||
|
* dispositionEventsEligible = true;
|
||||||
|
*
|
||||||
|
* Runs the cut off or retain action for
|
||||||
|
* elligible records.
|
||||||
|
*
|
||||||
|
* @author mrogers
|
||||||
|
*/
|
||||||
|
public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecuter
|
||||||
|
{
|
||||||
|
private static Log logger = LogFactory.getLog(DispositionLifecycleJobExecuter.class);
|
||||||
|
|
||||||
|
private RecordsManagementActionService recordsManagementActionService;
|
||||||
|
|
||||||
|
private NodeService nodeService;
|
||||||
|
|
||||||
|
private SearchService searchService;
|
||||||
|
|
||||||
|
public void setRecordsManagementActionService(RecordsManagementActionService recordsManagementActionService)
|
||||||
|
{
|
||||||
|
this.recordsManagementActionService = recordsManagementActionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchService(SearchService searchService)
|
||||||
|
{
|
||||||
|
this.searchService = searchService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJobExecuter#execute()
|
||||||
|
*/
|
||||||
|
public void execute()
|
||||||
|
{
|
||||||
|
logger.debug("Job Starting");
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("+TYPE:\"rma:dispositionAction\" ");
|
||||||
|
sb.append("+(@rma\\:dispositionAction:(\"cutoff\" OR \"retain\"))");
|
||||||
|
sb.append("+ISNULL:\"rma:dispositionActionCompletedAt\" ");
|
||||||
|
sb.append("+( ");
|
||||||
|
sb.append("@rma\\:dispositionEventsEligible:true ");
|
||||||
|
sb.append("OR @rma\\:dispositionAsOf:[MIN TO NOW] ");
|
||||||
|
sb.append(") ");
|
||||||
|
|
||||||
|
String query = sb.toString();
|
||||||
|
|
||||||
|
ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,
|
||||||
|
SearchService.LANGUAGE_LUCENE, query);
|
||||||
|
List<NodeRef> resultNodes = results.getNodeRefs();
|
||||||
|
results.close();
|
||||||
|
|
||||||
|
|
||||||
|
for (NodeRef node : resultNodes)
|
||||||
|
{
|
||||||
|
final NodeRef currentNode = node;
|
||||||
|
|
||||||
|
RetryingTransactionCallback<Boolean> processTranCB = new RetryingTransactionCallback<Boolean>()
|
||||||
|
{
|
||||||
|
public Boolean execute() throws Throwable
|
||||||
|
{
|
||||||
|
final String dispAction = (String) nodeService.getProperty(currentNode,
|
||||||
|
RecordsManagementModel.PROP_DISPOSITION_ACTION);
|
||||||
|
|
||||||
|
// Run "retain" and "cutoff" actions.
|
||||||
|
|
||||||
|
if (dispAction != null)
|
||||||
|
{
|
||||||
|
if (dispAction.equalsIgnoreCase("cutoff") ||
|
||||||
|
dispAction.equalsIgnoreCase("retain"))
|
||||||
|
{
|
||||||
|
ChildAssociationRef parent = nodeService.getPrimaryParent(currentNode);
|
||||||
|
if (parent.getTypeQName().equals(RecordsManagementModel.ASSOC_NEXT_DISPOSITION_ACTION))
|
||||||
|
{
|
||||||
|
// Check that the action is executable
|
||||||
|
RecordsManagementAction rmAction = recordsManagementActionService.getDispositionAction(dispAction);
|
||||||
|
if (rmAction.isExecutable(parent.getParentRef(), null) == true)
|
||||||
|
{
|
||||||
|
recordsManagementActionService.executeRecordsManagementAction(parent.getParentRef(), dispAction);
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Processed action: " + dispAction + "on" + parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.debug("The disposition action " + dispAction + " is not executable.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Now do the work, one action in each transaction
|
||||||
|
*/
|
||||||
|
retryingTransactionHelper.doInTransaction(processTranCB);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("Job Finished");
|
||||||
|
}
|
||||||
|
}
|
@@ -25,19 +25,14 @@ import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
|||||||
import org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagementNotificationHelper;
|
import org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagementNotificationHelper;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
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;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.cmr.search.ResultSet;
|
import org.alfresco.service.cmr.search.ResultSet;
|
||||||
import org.alfresco.service.cmr.search.SearchService;
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.quartz.Job;
|
|
||||||
import org.quartz.JobExecutionContext;
|
|
||||||
import org.quartz.JobExecutionException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This job finds all Vital Records which are due for review, optionally
|
* This job finds all Vital Records which are due for review, optionally
|
||||||
@@ -45,20 +40,37 @@ import org.quartz.JobExecutionException;
|
|||||||
*
|
*
|
||||||
* @author Neil McErlean
|
* @author Neil McErlean
|
||||||
*/
|
*/
|
||||||
public class NotifyOfRecordsDueForReviewJob implements Job
|
public class NotifyOfRecordsDueForReviewJobExecuter extends RecordsManagementJobExecuter
|
||||||
{
|
{
|
||||||
private static Log logger = LogFactory.getLog(NotifyOfRecordsDueForReviewJob.class);
|
private static Log logger = LogFactory.getLog(NotifyOfRecordsDueForReviewJobExecuter.class);
|
||||||
|
|
||||||
|
private RecordsManagementNotificationHelper recordsManagementNotificationHelper;
|
||||||
|
|
||||||
|
private NodeService nodeService;
|
||||||
|
|
||||||
|
private SearchService searchService;
|
||||||
|
|
||||||
|
public void setRecordsManagementNotificationHelper(
|
||||||
|
RecordsManagementNotificationHelper recordsManagementNotificationHelper)
|
||||||
|
{
|
||||||
|
this.recordsManagementNotificationHelper = recordsManagementNotificationHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchService(SearchService searchService)
|
||||||
|
{
|
||||||
|
this.searchService = searchService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
|
* @see org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJobExecuter#execute()
|
||||||
*/
|
*/
|
||||||
public void execute(JobExecutionContext context) throws JobExecutionException
|
public void execute()
|
||||||
{
|
{
|
||||||
final RecordsManagementNotificationHelper notificationHelper = (RecordsManagementNotificationHelper)context.getJobDetail().getJobDataMap().get("recordsManagementNotificationHelper");
|
|
||||||
final NodeService nodeService = (NodeService) context.getJobDetail().getJobDataMap().get("nodeService");
|
|
||||||
final SearchService searchService = (SearchService) context.getJobDetail().getJobDataMap().get("searchService");
|
|
||||||
final TransactionService trxService = (TransactionService) context.getJobDetail().getJobDataMap().get("transactionService");
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("Job " + this.getClass().getSimpleName() + " starting.");
|
logger.debug("Job " + this.getClass().getSimpleName() + " starting.");
|
||||||
@@ -91,8 +103,6 @@ public class NotifyOfRecordsDueForReviewJob implements Job
|
|||||||
//If we have something to do and a template to do it with
|
//If we have something to do and a template to do it with
|
||||||
if(resultNodes.size() != 0)
|
if(resultNodes.size() != 0)
|
||||||
{
|
{
|
||||||
RetryingTransactionHelper trn = trxService.getRetryingTransactionHelper();
|
|
||||||
|
|
||||||
//Send the email message - but we must not retry since email is not transactional
|
//Send the email message - but we must not retry since email is not transactional
|
||||||
RetryingTransactionCallback<Boolean> txCallbackSendEmail = new RetryingTransactionCallback<Boolean>()
|
RetryingTransactionCallback<Boolean> txCallbackSendEmail = new RetryingTransactionCallback<Boolean>()
|
||||||
{
|
{
|
||||||
@@ -100,7 +110,7 @@ public class NotifyOfRecordsDueForReviewJob implements Job
|
|||||||
public Boolean execute() throws Throwable
|
public Boolean execute() throws Throwable
|
||||||
{
|
{
|
||||||
// Send notification
|
// Send notification
|
||||||
notificationHelper.recordsDueForReviewEmailNotification(resultNodes);
|
recordsManagementNotificationHelper.recordsDueForReviewEmailNotification(resultNodes);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -122,10 +132,10 @@ public class NotifyOfRecordsDueForReviewJob implements Job
|
|||||||
/**
|
/**
|
||||||
* Now do the work, one action in each transaction
|
* Now do the work, one action in each transaction
|
||||||
*/
|
*/
|
||||||
trn.setMaxRetries(0); // don't retry the send email
|
retryingTransactionHelper.setMaxRetries(0); // don't retry the send email
|
||||||
trn.doInTransaction(txCallbackSendEmail);
|
retryingTransactionHelper.doInTransaction(txCallbackSendEmail);
|
||||||
trn.setMaxRetries(10);
|
retryingTransactionHelper.setMaxRetries(10);
|
||||||
trn.doInTransaction(txUpdateNodesCallback);
|
retryingTransactionHelper.doInTransaction(txUpdateNodesCallback);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
@@ -24,7 +24,6 @@ import java.util.List;
|
|||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutor;
|
import org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutor;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutorRegistry;
|
import org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutorRegistry;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
|
||||||
import org.alfresco.repo.policy.BehaviourFilter;
|
import org.alfresco.repo.policy.BehaviourFilter;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
@@ -37,20 +36,16 @@ import org.alfresco.service.cmr.search.ResultSet;
|
|||||||
import org.alfresco.service.cmr.search.SearchService;
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.quartz.Job;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.quartz.JobExecutionContext;
|
|
||||||
import org.quartz.JobExecutionException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Job to publish any pending updates on marked node references.
|
* Job to publish any pending updates on marked node references.
|
||||||
*
|
*
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
*/
|
*/
|
||||||
public class PublishUpdatesJob implements Job, RecordsManagementModel
|
public class PublishUpdatesJobExecuter extends RecordsManagementJobExecuter
|
||||||
{
|
{
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static Log logger = LogFactory.getLog(PublishUpdatesJob.class);
|
private static Log logger = LogFactory.getLog(PublishUpdatesJobExecuter.class);
|
||||||
|
|
||||||
/** Node service */
|
/** Node service */
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
@@ -58,26 +53,34 @@ public class PublishUpdatesJob implements Job, RecordsManagementModel
|
|||||||
/** Search service */
|
/** Search service */
|
||||||
private SearchService searchService;
|
private SearchService searchService;
|
||||||
|
|
||||||
/** Retrying transaction helper */
|
|
||||||
private RetryingTransactionHelper retryingTransactionHelper;
|
|
||||||
|
|
||||||
/** Publish executor register */
|
/** Publish executor register */
|
||||||
private PublishExecutorRegistry register;
|
private PublishExecutorRegistry publishExecutorRegistry;
|
||||||
|
|
||||||
/** Behaviour filter */
|
/** Behaviour filter */
|
||||||
private BehaviourFilter behaviourFilter;
|
private BehaviourFilter behaviourFilter;
|
||||||
|
|
||||||
/** Indicates whether the job bean has been initialised or not */
|
public void setNodeService(NodeService nodeService)
|
||||||
private boolean initialised = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
|
|
||||||
*/
|
|
||||||
public void execute(JobExecutionContext context) throws JobExecutionException
|
|
||||||
{
|
{
|
||||||
// Initialise the service references
|
this.nodeService = nodeService;
|
||||||
initServices(context);
|
}
|
||||||
|
|
||||||
|
public void setSearchService(SearchService searchService)
|
||||||
|
{
|
||||||
|
this.searchService = searchService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublishExecutorRegistry(PublishExecutorRegistry publishExecutorRegistry)
|
||||||
|
{
|
||||||
|
this.publishExecutorRegistry = publishExecutorRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
|
||||||
|
{
|
||||||
|
this.behaviourFilter = behaviourFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute()
|
||||||
|
{
|
||||||
if (logger.isDebugEnabled() == true)
|
if (logger.isDebugEnabled() == true)
|
||||||
{
|
{
|
||||||
logger.debug("Job Starting");
|
logger.debug("Job Starting");
|
||||||
@@ -156,25 +159,6 @@ public class PublishUpdatesJob implements Job, RecordsManagementModel
|
|||||||
return retryingTransactionHelper.doInTransaction(execution, true);
|
return retryingTransactionHelper.doInTransaction(execution, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialise service based on the job execution context
|
|
||||||
* @param context job execution context
|
|
||||||
*/
|
|
||||||
private void initServices(JobExecutionContext context)
|
|
||||||
{
|
|
||||||
if (initialised == false)
|
|
||||||
{
|
|
||||||
// Get references to the required services
|
|
||||||
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
|
|
||||||
nodeService = (NodeService)jobDataMap.get("nodeService");
|
|
||||||
searchService = (SearchService)jobDataMap.get("searchService");
|
|
||||||
retryingTransactionHelper = (RetryingTransactionHelper)jobDataMap.get("retryingTransactionHelper");
|
|
||||||
register = (PublishExecutorRegistry)jobDataMap.get("publishExecutorRegistry");
|
|
||||||
behaviourFilter = (BehaviourFilter)jobDataMap.get("behaviourFilter");
|
|
||||||
initialised = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the node as publish in progress. This is often used as a marker to prevent any further updates
|
* Mark the node as publish in progress. This is often used as a marker to prevent any further updates
|
||||||
* to a node.
|
* to a node.
|
||||||
@@ -235,7 +219,7 @@ public class PublishUpdatesJob implements Job, RecordsManagementModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the publish executor
|
// Get the publish executor
|
||||||
PublishExecutor executor = register.get(updateTo);
|
PublishExecutor executor = publishExecutorRegistry.get(updateTo);
|
||||||
if (executor == null)
|
if (executor == null)
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled() == true)
|
if (logger.isDebugEnabled() == true)
|
@@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009-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.module.org_alfresco_module_rm.job;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.repo.lock.JobLockService;
|
||||||
|
import org.alfresco.repo.lock.LockAcquisitionException;
|
||||||
|
import org.alfresco.repo.lock.JobLockService.JobLockRefreshCallback;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.quartz.Job;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base records management job implementation.
|
||||||
|
* <p>
|
||||||
|
* Delegates job execution and ensures locking
|
||||||
|
* is enforced.
|
||||||
|
*
|
||||||
|
* @author Roy Wetherall
|
||||||
|
*/
|
||||||
|
public class RecordsManagementJob implements Job
|
||||||
|
{
|
||||||
|
private static long DEFAULT_TIME = 2000L;
|
||||||
|
|
||||||
|
private JobLockService jobLockService;
|
||||||
|
|
||||||
|
private RecordsManagementJobExecuter jobExecuter;
|
||||||
|
|
||||||
|
private String jobName;
|
||||||
|
|
||||||
|
private QName getLockQName()
|
||||||
|
{
|
||||||
|
return QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, jobName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to get the lock. If the lock couldn't be taken, then <tt>null</tt> is returned.
|
||||||
|
*
|
||||||
|
* @return Returns the lock token or <tt>null</tt>
|
||||||
|
*/
|
||||||
|
private String getLock()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return jobLockService.getLock(getLockQName(), DEFAULT_TIME);
|
||||||
|
}
|
||||||
|
catch (LockAcquisitionException e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(JobExecutionContext context) throws JobExecutionException
|
||||||
|
{
|
||||||
|
// get the job lock service
|
||||||
|
jobLockService = (JobLockService)context.getJobDetail().getJobDataMap().get("jobLockService");
|
||||||
|
if (jobLockService == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Job lock service has not been specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the job executer
|
||||||
|
jobExecuter = (RecordsManagementJobExecuter)context.getJobDetail().getJobDataMap().get("jobExecuter");
|
||||||
|
if (jobExecuter == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Job executer has not been specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the job name
|
||||||
|
jobName = (String)context.getJobDetail().getJobDataMap().get("jobName");
|
||||||
|
if (jobName == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Job name has not been specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Void>()
|
||||||
|
{
|
||||||
|
public Void doWork() throws Exception
|
||||||
|
{
|
||||||
|
// try and get the lock
|
||||||
|
String lockToken = getLock();
|
||||||
|
if (lockToken == null)
|
||||||
|
{
|
||||||
|
// exit
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use a flag to keep track of the running job
|
||||||
|
final AtomicBoolean running = new AtomicBoolean(true);
|
||||||
|
jobLockService.refreshLock(lockToken, getLockQName(), DEFAULT_TIME, new JobLockRefreshCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean isActive()
|
||||||
|
{
|
||||||
|
return running.get();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void lockReleased()
|
||||||
|
{
|
||||||
|
running.set(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// do work
|
||||||
|
jobExecuter.execute();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// The lock will self-release if answer isActive in the negative
|
||||||
|
running.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009-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.module.org_alfresco_module_rm.job;
|
||||||
|
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roy Wetherall
|
||||||
|
*/
|
||||||
|
public abstract class RecordsManagementJobExecuter implements RecordsManagementModel
|
||||||
|
{
|
||||||
|
protected RetryingTransactionHelper retryingTransactionHelper;
|
||||||
|
|
||||||
|
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
|
||||||
|
{
|
||||||
|
this.retryingTransactionHelper = retryingTransactionHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void execute();
|
||||||
|
}
|
Reference in New Issue
Block a user