Anomalie au déclenchement d'un timer

cancel
Showing results for 
Search instead for 
Did you mean: 
mlagneaux
Active Member

Anomalie au déclenchement d'un timer

Bonjour,

Je travaille sur Alfresco 3.4e.
J'ai modifié le modèle de données afin d'ajouter un statut (Brouillon, Validé, etc) à mes documents et j'ai développé le workflow suivant dont le but est de faire évoluer le statut du document associé au workflow.

Voici la définition du processus de mon workflow :

<?xml version="1.0" encoding="UTF-8"?>

<process-definition  xmlns="urn:jbpm.org:jpdl-3.1"  name="mbswf:validateByTeam">

   <!–Definition des swimlanes–>
   <swimlane name="initiator">
   </swimlane>
   
   <swimlane name="validationTeam">
        <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
            <actor>#{mbswf_validationTeam}</actor>
        </assignment>   
    </swimlane>

   <!– Definition des etapes –>
   <start-state name="start-state1">
      <task name="mbswf:readPermissionStartTask" swimlane="initiator"/>
      <transition to="teamSelection">
         <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
            <script>
               <variable name="oldStatusName" access="write" />
               <expression>
                  var doc = bpm_package.children[0];
                  oldStatusName = doc.properties["mbs:statusName"] ;
               </expression>
            </script>
         </action>
         <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
            <script>
               <variable name="newStatusName" access="write" />
               <expression>
                  newStatusName = "Validate";
               </expression>
            </script>
         </action>
         <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
            <script>
               <variable name="statusNameValue" access="write" />
               <expression>
                  statusNameValue = "In Progress";
               </expression>
            </script>
         </action>
      </transition>
   </start-state>


   <task-node name="teamSelection">
      <task name="mbswf:validateByTeam_teamSelection" swimlane="initiator"/>
      <transition to="teamTaskAssignment" name="teamSelected">
         <action class="fr.mbs.bpm.SetStatusNameAction"/>
      </transition>
   </task-node>

   <node name="teamTaskAssignment">
      <action class="org.alfresco.repo.workflow.jbpm.ForEachFork">
         <foreach>#{mbswf_validationTeam}</foreach>
         <var>validator</var>
      </action>
      <event type="node-enter">
         <script>
            <variable name="reject_count" access="write" />
            <expression>
               reject_count = 0;
            </expression>
         </script>
      </event>
      <transition to="validation"></transition>
   </node>

   <task-node name="validation">
      <task name="mbswf:validateByTeam_validation">
         <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
              <actor>#{validator}</actor>
            </assignment>
         <timer name="validationTimer" duedate="5 minutes" transition="ok">
            <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
               <script>
                  logger.log("Validation timer expired");
               </script>
            </action>
         </timer>
      </task>
      <transition to="join1" name="ok"></transition>
      <transition to="join1" name="ko">
         <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
            <script>
               <variable name="reject_count" access="read,write" />
               <expression>
                  reject_count = reject_count + 1;
               </expression>
            </script>
         </action>
      </transition>
   </task-node>

   <join name="join1">
      <transition to="isRejected"></transition>
   </join>

   <decision name="isRejected">
      <transition to="end-state1" name="documentValidated">
         <condition>#{reject_count == 0}</condition>
         <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
            <script>
               <variable name="newStatusName" access="read" />
               <variable name="statusNameValue" access="write" />
               <expression>
                  statusNameValue = newStatusName;
               </expression>
            </script>
         </action>
         <action class="fr.mbs.bpm.SetStatusNameAndDateAction"/>
      </transition>
      <transition to="end-state2" name="documentValidationRejected">
         <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
            <script>
               <variable name="oldStatusName" access="read" />
               <variable name="statusNameValue" access="write" />
               <expression>
                  statusNameValue = oldStatusName;
               </expression>
            </script>
         </action>
         <action class="fr.mbs.bpm.SetStatusNameAction"/>
      </transition>
   </decision>

   <end-state name="end-state1"></end-state>

   <end-state name="end-state2"></end-state>


</process-definition>
La tâche teamSelection permet de choisir plusieurs utilisateurs (association vers plusieurs cmSmiley Tongueerson dans le type mbswf:validateByTeam_teamSelection) à qui l'on affecte ensuite des tâches de validation.

La tâche de validation présente un timer qui déclenche au bout de 5 minutes la transition ok.

Les classes SetStatusNameAction et SetStatusNameAndDateAction modifient les propriétés du noeud associé au workflow (statut et date de validité du statut).
Voici par exemple le contenu de SetStatusNameAndDateAction :

package fr.mbs.bpm;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Properties;

import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.repo.workflow.jbpm.JBPMNode;
import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
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.namespace.RegexQNamePattern;
import org.apache.log4j.Logger;
import org.jbpm.graph.exe.ExecutionContext;
import org.springframework.beans.factory.BeanFactory;

import fr.mbs.model.MbsModel;

public class SetStatusNameAndDateAction extends JBPMSpringActionHandler {
   
   private static final long serialVersionUID = 1L;

   private static Logger logger = Logger.getLogger(SetStatusNameAndDateAction.class);
   
   private static final String VAR_STATUS_NAME_VALUE = "statusNameValue";
   private static final String VAR_BPM_PACKAGE = "bpm_package";
   private static final String PROP_STATUS_VALIDITY_DURATION = "status.validity.duration";
   private static final int DEFAULT_STATUS_VALIDITY_DURATION = 12;
   
   private NodeService nodeService;
   private Properties mbsProperties;

   public void execute(ExecutionContext executionContext) throws Exception {
      logger.debug("Inside SetStatusNameAndDateAction.execute()");
      
      // get the status name
      final String statusName = (String)executionContext.getContextInstance().getVariable(VAR_STATUS_NAME_VALUE);
      
      // get the workflow package
      NodeRef pkg = ((JBPMNode)executionContext.getContextInstance().getVariable(VAR_BPM_PACKAGE)).getNodeRef();
            
      List<ChildAssociationRef> childrenList = this.nodeService.getChildAssocs(pkg, 
            WorkflowModel.ASSOC_PACKAGE_CONTAINS, RegexQNamePattern.MATCH_ALL);
      for(ChildAssociationRef childAssoc:childrenList){
         // get child node ref
         final NodeRef nodeRef = childAssoc.getChildRef();
         final Calendar statusDate = getStatusDate();
         logger.debug("Inside SetStatusNameAndDateAction.execute() - processing nodeRef : "+nodeRef);
         
         AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>(){
            public Object doWork() throws Exception
            {
               nodeService.setProperty(nodeRef, MbsModel.PROP_STATUS_NAME, statusName);
               nodeService.setProperty(nodeRef, MbsModel.PROP_STATUS_DATE, statusDate);

               return null;
            }
         }, AuthenticationUtil.getAdminUserName());
         
      }
   }

   @Override
   protected void initialiseHandler(BeanFactory factory) {
      this.nodeService = (NodeService)factory.getBean("nodeService");
      this.mbsProperties = (Properties)factory.getBean("mbs-properties");
   }
   
   //————————————————————————————————————-
   // Helpers
   
   private Calendar getStatusDate() {
      Calendar statusDate = new GregorianCalendar();
      int statusValidityDuration = getStatusValidityDuration();
      statusDate.add(Calendar.MONTH, statusValidityDuration);
      
      return statusDate;
   }
   
   private int getStatusValidityDuration() {
      int statusValidityDuration;
      
      String statusValidityDurationProperty = this.mbsProperties.getProperty(PROP_STATUS_VALIDITY_DURATION);
      
      try{
         statusValidityDuration = Integer.parseInt(statusValidityDurationProperty);
         
         if(statusValidityDuration < 1){
            statusValidityDuration = DEFAULT_STATUS_VALIDITY_DURATION;
         }
      }
      catch(NumberFormatException e){
         statusValidityDuration = DEFAULT_STATUS_VALIDITY_DURATION;
      }
      
      return statusValidityDuration;
   }

}

Au déclenchement du timer, j'obtiens l'erreur suivante dans les logs :

09:23:48,826  ERROR [workflow.jbpm.AlfrescoJobExecutorThread] failed to execute Timer(validationTimer,2011-09-13 09:22:47,000,TaskInstance(mbswf:validateByTeam_validation),Token(/FOREACHFORK.0))
org.alfresco.error.AlfrescoRuntimeException: 08130003 Failed to execute transaction-level behaviour public abstract void org.alfresco.repo.node.NodeServicePolicies$OnUpdatePropertiesPolicy.onUpdateProperties(org.alfresco.service.cmr.repository.NodeRef,java.util.Map,java.util.Map) in transaction 4a4923d1-7dd2-4920-9a3b-56ebb3b05a59
   at org.alfresco.repo.policy.TransactionBehaviourQueue.execute(TransactionBehaviourQueue.java:195)
   at org.alfresco.repo.policy.TransactionBehaviourQueue.beforeCommit(TransactionBehaviourQueue.java:127)
   at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.doBeforeCommit(AlfrescoTransactionSupport.java:732)
   at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.doBeforeCommit(AlfrescoTransactionSupport.java:712)
   at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.beforeCommit(AlfrescoTransactionSupport.java:672)
   at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:927)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:737)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:394)
   at org.alfresco.util.transaction.SpringAwareUserTransaction.commit(SpringAwareUserTransaction.java:472)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:403)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:253)
   at org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutorThread.executeJob(AlfrescoJobExecutorThread.java:187)
   at org.jbpm.job.executor.JobExecutorThread.run(JobExecutorThread.java:60)
Caused by: net.sf.acegisecurity.AuthenticationCredentialsNotFoundException: A valid SecureContext was not provided in the RequestContext
   at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:477)
   at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:355)
   at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:77)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:44)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditMethodInterceptor.proceedWithAudit(AuditMethodInterceptor.java:217)
   at org.alfresco.repo.audit.AuditMethodInterceptor.proceed(AuditMethodInterceptor.java:184)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:137)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy8.exists(Unknown Source)
   at org.alfresco.repo.rendition.RenditionedAspect.onUpdateProperties(RenditionedAspect.java:140)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.alfresco.repo.policy.JavaBehaviour$JavaMethodInvocationHandler.invoke(JavaBehaviour.java:173)
   at $Proxy12.onUpdateProperties(Unknown Source)
   at sun.reflect.GeneratedMethodAccessor402.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.alfresco.repo.policy.TransactionBehaviourQueue.execute(TransactionBehaviourQueue.java:183)
   … 14 more
Savez-vous d'où peut venir ce problème ?
Les développements concernant ce workflow (modification du contentModel, définition d'un modèle pour le workflow, déploiement du workflow, classe appelée dans le workflow) sont les seules modifications apportées à Alfresco.
Je n'ai pas de problème sur mes transitions ok ou ko lorsqu'elles sont déclenchées par l'utilisateur.

Merci d'avance pour votre aide. N'hésitez pas si vous avez besoin d'infos complémentaires.
1 Reply
mlagneaux
Active Member

Re: Anomalie au déclenchement d'un timer

J'ai créé un ticket sur le JIRA Alfresco :
http://issues.alfresco.com/jira/browse/ALF-10389